Hello community, here is the log from the commit of package ignition for openSUSE:Leap:15.2 checked in at 2020-03-26 05:41:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/ignition (Old) and /work/SRC/openSUSE:Leap:15.2/.ignition.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ignition" Thu Mar 26 05:41:37 2020 rev:2 rq:788151 version:2.2.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/ignition/ignition.changes 2020-03-06 12:40:32.206730194 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.ignition.new.3160/ignition.changes 2020-03-26 05:41:57.151296626 +0100 @@ -1,0 +2,29 @@ +Tue Mar 24 12:58:48 UTC 2020 - Ignaz Forster <[email protected]> + +- Add 0001-Support-more-architectures.patch: + Allow builing on i586 (and other architectures) again + +------------------------------------------------------------------- +Tue Mar 24 07:45:25 UTC 2020 - [email protected] + +- Update to version 2.2.0: + * news: add notes for 2.2.0 + * Fix ignition config for the instantiated unit test + * Fix enabling systemd instantiated services + * providers/qemu: support Ignition block device on s390x and ppc64le + * blkid: Explicitly use C int variable for numParts + * tests: don't panic after failing to run Ignition + * platform: sort providers + * ci: migrate to new coreos-ci project + * OWNERS: add OWNERS file + * Add Exoscale provider + * docs: minor fixes to platforms page + * ci: hook up to CoreOS CI + * providers/vultr: Add Vultr provider + * Throw error if SSH keys could not be written + * stages/files: don't relabel /home and /root symlinks +- Drop 0001-Throw-error-if-SSH-keys-could-not-be-written.patch +- Added explicit Recommends for helper applications + [boo#1167289] + +------------------------------------------------------------------- Old: ---- 0001-Throw-error-if-SSH-keys-could-not-be-written.patch ignition-2.1.1.tar.xz New: ---- 0001-Support-more-architectures.patch ignition-2.2.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ignition.spec ++++++ --- /var/tmp/diff_new_pack.AaxczC/_old 2020-03-26 05:41:57.679296900 +0100 +++ /var/tmp/diff_new_pack.AaxczC/_new 2020-03-26 05:41:57.683296902 +0100 @@ -17,16 +17,27 @@ Name: ignition -Version: 2.1.1 +Version: 2.2.0 Release: 0 Summary: First boot installer and configuration tool License: Apache-2.0 Group: System/Management URL: https://github.com/coreos/ignition Source: %{name}-%{version}.tar.xz -Patch1: 0001-Throw-error-if-SSH-keys-could-not-be-written.patch +Patch1: 0001-Support-more-architectures.patch Patch2: 0002-allow-multiple-mounts-of-same-device.patch Requires: dracut +Recommends: /sbin/mkfs.btrfs +Recommends: /sbin/mkfs.ext4 +Recommends: /sbin/mkfs.vfat +Recommends: /sbin/mkfs.xfs +Recommends: /sbin/mkswap +Recommends: /sbin/udevadm +Recommends: /usr/sbin/groupadd +Recommends: /usr/sbin/sgdisk +Recommends: /usr/sbin/useradd +Recommends: /usr/sbin/usermod +Suggests: /sbin/mdadm BuildRequires: dracut BuildRequires: libblkid-devel BuildRequires: golang(API) >= 1.12 ++++++ 0001-Support-more-architectures.patch ++++++ >From 7d46257741a60291504b998ce0bc5ea1f2e28d00 Mon Sep 17 00:00:00 2001 From: Ignaz Forster <[email protected]> Date: Tue, 24 Mar 2020 13:41:43 +0100 Subject: [PATCH] Support more architectures References: gh#coreos/ignition#944 Upstream: submitted Commit 3b930b made it impossible to build Ignition on any other arch then s390x, ppc64le, amd64 or arm64 by explicitly stating the allowed platforms. This made it impossible to build e.g. for 386. Continue to use the fw_cfg interface as default instead. --- internal/providers/qemu/qemu_fwcfg.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/providers/qemu/qemu_fwcfg.go b/internal/providers/qemu/qemu_fwcfg.go index 0758943..c485d6f 100644 --- a/internal/providers/qemu/qemu_fwcfg.go +++ b/internal/providers/qemu/qemu_fwcfg.go @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build amd64 arm64 +// +build !s390x,!ppc64le -// The QEMU provider on amd64 and arm64 fetches a local configuration from the -// firmware config interface (opt/com.coreos/config). +// The default QEMU provider fetches a local configuration from the firmware +// config interface (opt/com.coreos/config). Platforms without support for +// qemu_fw_cfg should use the blockdev implementation instead. package qemu -- 2.25.1 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.AaxczC/_old 2020-03-26 05:41:57.711296917 +0100 +++ /var/tmp/diff_new_pack.AaxczC/_new 2020-03-26 05:41:57.711296917 +0100 @@ -1,7 +1,7 @@ <services> <service name="tar_scm" mode="disabled"> - <param name="version">2.1.1</param> - <param name="revision">v2.1.1</param> + <param name="version">2.2.0</param> + <param name="revision">v2.2.0</param> <param name="url">git://github.com/coreos/ignition.git</param> <param name="scm">git</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.AaxczC/_old 2020-03-26 05:41:57.739296931 +0100 +++ /var/tmp/diff_new_pack.AaxczC/_new 2020-03-26 05:41:57.739296931 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/coreos/ignition.git</param> - <param name="changesrevision">40c0b57b7606bd23210059c5554f151776a1d64b</param> + <param name="changesrevision">fc98a80cb4184bfd1b7aff8d92d0047022850cf6</param> </service> </servicedata> \ No newline at end of file ++++++ ignition-2.1.1.tar.xz -> ignition-2.2.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/.cci.jenkinsfile new/ignition-2.2.0/.cci.jenkinsfile --- old/ignition-2.1.1/.cci.jenkinsfile 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/.cci.jenkinsfile 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,11 @@ +// Documentation: https://github.com/coreos/coreos-ci/blob/master/README-upstream-ci.md + +cosaPod(buildroot: true) { + checkout scm + + // hack to satisfy golang compiler wanting to cache things + shwrap("mkdir cache") + withEnv(["XDG_CACHE_HOME=${env.WORKSPACE}/cache"]) { + fcosBuild(make: true) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/NEWS new/ignition-2.2.0/NEWS --- old/ignition-2.1.1/NEWS 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/NEWS 2020-03-23 23:29:56.000000000 +0100 @@ -1,3 +1,21 @@ +23-Mar-2020 Ignition 2.2.0 + + Features: + + - Add Exoscale and Vultr providers + - On QEMU/s390x and QEMU/ppc64le, fetch Ignition config from a virtio + block device (experimental) + + Changes: + + - Don't relabel /root and /home + + Bug Fixes: + + - Fix enabling systemd instantiated services + - Fail if SSH keys cannot be written + - Fix partition creation on s390x + 13-Dec-2019 Ignition 2.1.1 Bug Fixes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/OWNERS new/ignition-2.2.0/OWNERS --- old/ignition-2.1.1/OWNERS 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/OWNERS 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,19 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +# This matches the fedora-coreos-tools team members. +# XXX: figure out a way to just have it use GitHub team membership directly. + +approvers: + - arithx + - ashcrow + - bgilbert + - cgwalters + - darkmuggle + - dustymabe + - jlebon + - LorbusChris + - lucab + - miabbott + - mike-nguyen + - yuqi-zhang + - zonggen diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/config/shared/errors/errors.go new/ignition-2.2.0/config/shared/errors/errors.go --- old/ignition-2.1.1/config/shared/errors/errors.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/config/shared/errors/errors.go 2020-03-23 23:29:56.000000000 +0100 @@ -74,6 +74,8 @@ // Systemd section errors ErrInvalidSystemdExt = errors.New("invalid systemd unit extension") ErrInvalidSystemdDropinExt = errors.New("invalid systemd drop-in extension") + ErrNoSystemdExt = errors.New("no systemd unit extension") + ErrInvalidInstantiatedUnit = errors.New("invalid systemd instantiated unit") // Misc errors ErrInvalidScheme = errors.New("invalid url scheme") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/doc/supported-platforms.md new/ignition-2.2.0/doc/supported-platforms.md --- old/ignition-2.1.1/doc/supported-platforms.md 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/doc/supported-platforms.md 2020-03-23 23:29:56.000000000 +0100 @@ -3,16 +3,18 @@ Ignition is currently only supported for the following platforms: * [Bare Metal] - Use the `ignition.config.url` kernel parameter to provide a URL to the configuration. The URL can use the `http://`, `https://`, `tftp://`, or `s3://` schemes to specify a remote config. -* [Amazon Web Services] - Ignition will read its configuration from the instance userdata. SSH keys are handled by coreos-metadata. -* [Microsoft Azure] - Ignition will read its configuration from the custom data provided to the instance. SSH keys are handled by the Azure Linux Agent. +* [Amazon Web Services] - Ignition will read its configuration from the instance userdata. Cloud SSH keys are handled separately. +* [Microsoft Azure] - Ignition will read its configuration from the custom data provided to the instance. Cloud SSH keys are handled separately. * [VMware] - Use the VMware Guestinfo variables `ignition.config.data` and `ignition.config.data.encoding` to provide the config and its encoding to the virtual machine. Valid encodings are "", "base64", and "gzip+base64". Guestinfo variables can be provided directly or via an OVF environment, with priority given to variables specified directly. -* [Google Compute Platform] - Ignition will read its configuration from the instance metadata entry named "user-data". SSH keys are handled by coreos-metadata. -* [Packet] - Ignition will read its configuration from the instance userdata. SSH keys are handled by coreos-metadata. +* [Google Compute Platform] - Ignition will read its configuration from the instance metadata entry named "user-data". Cloud SSH keys are handled separately. +* [Packet] - Ignition will read its configuration from the instance userdata. Cloud SSH keys are handled separately. * [QEMU] - Ignition will read its configuration from the 'opt/com.coreos/config' key on the QEMU Firmware Configuration Device (available in QEMU 2.4.0 and higher). -* [DigitalOcean] - Ignition will read its configuration from the droplet userdata. SSH keys and network configuration are handled by coreos-metadata. +* [DigitalOcean] - Ignition will read its configuration from the droplet userdata. Cloud SSH keys and network configuration are handled separately. * [zVM] - Ignition will read its configuration from the reader device directly. The vmur program is necessary, which requires the vmcp and vmur kernel module as prerequisite, and the corresponding z/VM virtual unit record devices (in most cases 000c as reader, 000d as punch) must be set online. -Ignition is under active development so expect this list to expand in the coming months. +Ignition is under active development, so this list may grow over time. + +For most cloud providers, cloud SSH keys and custom network configuration are handled by [Afterburn] or by platform-specific agents. [Bare Metal]: https://github.com/coreos/docs/blob/master/os/installing-to-disk.md [Amazon Web Services]: https://github.com/coreos/docs/blob/master/os/booting-on-ec2.md @@ -22,3 +24,6 @@ [Packet]: https://github.com/coreos/docs/blob/master/os/booting-on-packet.md [QEMU]: https://github.com/qemu/qemu/blob/d75aa4372f0414c9960534026a562b0302fcff29/docs/specs/fw_cfg.txt [DigitalOcean]: https://github.com/coreos/docs/blob/master/os/booting-on-digitalocean.md +[zVM]: http://www.vm.ibm.com/overview/ + +[Afterburn]: https://github.com/coreos/afterburn diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/stages/files/passwd.go new/ignition-2.2.0/internal/exec/stages/files/passwd.go --- old/ignition-2.1.1/internal/exec/stages/files/passwd.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/stages/files/passwd.go 2020-03-23 23:29:56.000000000 +0100 @@ -68,9 +68,7 @@ s.relabel(deglobbed...) s.relabel( "/etc/.pwd.lock", - "/home", - "/root", - // for OSTree-based systems (newer restorecon doesn't follow symlinks) + // for OSTree-based systems "/var/home", "/var/roothome", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/stages/files/units.go new/ignition-2.2.0/internal/exec/stages/files/units.go --- old/ignition-2.1.1/internal/exec/stages/files/units.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/stages/files/units.go 2020-03-23 23:29:56.000000000 +0100 @@ -19,35 +19,72 @@ "path/filepath" "strings" + "github.com/coreos/ignition/v2/config/shared/errors" "github.com/coreos/ignition/v2/config/v3_1_experimental/types" "github.com/coreos/ignition/v2/internal/distro" "github.com/coreos/ignition/v2/internal/exec/util" + "github.com/coreos/ignition/v2/internal/systemd" ) +// Preset holds the information about +// a given systemd unit. +type Preset struct { + unit string + enabled bool + instantiatable bool + instances []string +} + +// warnOnOldSystemdVersion checks the version of Systemd +// in a given system and prints a warning if older than 240. +func (s *stage) warnOnOldSystemdVersion() error { + systemdVersion, err := systemd.GetSystemdVersion() + if err != nil { + return err + } + if systemdVersion < 240 { + if err := s.Logger.Warning("The version of systemd (%q) is less than 240. Enabling/disabling instantiated units may not work. See https://github.com/coreos/ignition/issues/586 for more information.", systemdVersion); err != nil { + return err + } + } + return nil +} + // createUnits creates the units listed under systemd.units. func (s *stage) createUnits(config types.Config) error { - enabledOneUnit := false + presets := make(map[string]*Preset) for _, unit := range config.Systemd.Units { if err := s.writeSystemdUnit(unit, false); err != nil { return err } if unit.Enabled != nil { + // identifier keyword is used to distinguish systemd units + // which are either enabled or disabled. Appending + // it to a unitName will avoid overwriting the existing + // unitName's instance if the state of the unit is different. + identifier := "disabled" if *unit.Enabled { - if err := s.Logger.LogOp( - func() error { return s.EnableUnit(unit) }, - "enabling unit %q", unit.Name, - ); err != nil { + identifier = "enabled" + } + if strings.Contains(unit.Name, "@") { + unitName, instance, err := parseInstanceUnit(unit) + if err != nil { return err } + key := fmt.Sprintf("%s-%s", unitName, identifier) + if _, ok := presets[key]; ok { + presets[key].instances = append(presets[key].instances, instance) + } else { + presets[key] = &Preset{unitName, *unit.Enabled, true, []string{instance}} + } } else { - if err := s.Logger.LogOp( - func() error { return s.DisableUnit(unit) }, - "disabling unit %q", unit.Name, - ); err != nil { - return err + key := fmt.Sprintf("%s-%s", unit.Name, identifier) + if _, ok := presets[unit.Name]; !ok { + presets[key] = &Preset{unit.Name, *unit.Enabled, false, []string{}} + } else { + return fmt.Errorf("%q key is already present in the presets map", key) } } - enabledOneUnit = true } if unit.Mask != nil && *unit.Mask { relabelpath := "" @@ -64,10 +101,71 @@ s.relabel(relabelpath) } } - // and relabel the preset file itself if we enabled/disabled something - if enabledOneUnit { - s.relabel(util.PresetPath) + // if we have presets then create the systemd preset file. + if len(presets) != 0 { + if err := s.createSystemdPresetFile(presets); err != nil { + return err + } + } + + return nil +} + +// parseInstanceUnit extracts the name and a corresponding instance +// for a given instantiated unit. +// e.g: [email protected] ==> [email protected] & instance=bar +func parseInstanceUnit(unit types.Unit) (string, string, error) { + at := strings.Index(unit.Name, "@") + if at == -1 { + return "", "", errors.ErrInvalidInstantiatedUnit + } + dot := strings.LastIndex(unit.Name, ".") + if dot == -1 { + return "", "", errors.ErrNoSystemdExt + } + instance := unit.Name[at+1 : dot] + serviceInstance := unit.Name[0:at+1] + unit.Name[dot:len(unit.Name)] + return serviceInstance, instance, nil +} + +// createSystemdPresetFile creates the presetfile for enabled/disabled +// systemd units. +func (s *stage) createSystemdPresetFile(presets map[string]*Preset) error { + hasInstanceUnit := false + for _, value := range presets { + unitString := value.unit + if value.instantiatable { + hasInstanceUnit = true + // Let's say we have two instantiated enabled units listed under + // the systemd units i.e. [email protected], [email protected] + // then the unitString will look like "[email protected] foo bar" + unitString = fmt.Sprintf("%s %s", unitString, strings.Join(value.instances, " ")) + } + if value.enabled { + if err := s.Logger.LogOp( + func() error { return s.EnableUnit(unitString) }, + "setting preset to enabled for %q", unitString, + ); err != nil { + return err + } + } else { + if err := s.Logger.LogOp( + func() error { return s.DisableUnit(unitString) }, + "setting preset to disabled for %q", unitString, + ); err != nil { + return err + } + } + } + // Print the warning if there's an instantiated unit present under + // the systemd units and the version of systemd in a given system + // is older than 240. + if hasInstanceUnit { + if err := s.warnOnOldSystemdVersion(); err != nil { + return err + } } + s.relabel(util.PresetPath) return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/stages/files/units_test.go new/ignition-2.2.0/internal/exec/stages/files/units_test.go --- old/ignition-2.1.1/internal/exec/stages/files/units_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/stages/files/units_test.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,76 @@ +// Copyright 2020 CoreOS, 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 files + +import ( + "reflect" + "testing" + + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" +) + +func TestParseInstanceUnit(t *testing.T) { + type in struct { + unit types.Unit + } + type out struct { + unitName string + instance string + parseErr error + } + tests := []struct { + in in + out out + }{ + {in: in{types.Unit{Name: "[email protected]"}}, + out: out{unitName: "[email protected]", instance: "bar", + parseErr: nil}, + }, + + {in: in{types.Unit{Name: "[email protected]"}}, + out: out{unitName: "[email protected]", instance: "foo", + parseErr: nil}, + }, + {in: in{types.Unit{Name: "echo.service"}}, + out: out{unitName: "", instance: "", + parseErr: errors.ErrInvalidInstantiatedUnit}, + }, + {in: in{types.Unit{Name: "echo@fooservice"}}, + out: out{unitName: "", instance: "", + parseErr: errors.ErrNoSystemdExt}, + }, + {in: in{types.Unit{Name: "[email protected]"}}, + out: out{unitName: "[email protected]", instance: "", + parseErr: nil}, + }, + {in: in{types.Unit{Name: "[email protected]"}}, + out: out{unitName: "[email protected]", instance: "9.3-main", + parseErr: nil}, + }, + } + for i, test := range tests { + unitName, instance, err := parseInstanceUnit(test.in.unit) + if test.out.parseErr != err { + t.Errorf("#%d: bad error: want %v, got %v", i, test.out.parseErr, err) + } + if !reflect.DeepEqual(test.out.unitName, unitName) { + t.Errorf("#%d: bad unitName: want %v, got %v", i, test.out.unitName, unitName) + } + if !reflect.DeepEqual(test.out.instance, instance) { + t.Errorf("#%d: bad instance: want %v, got %v", i, test.out.instance, instance) + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/util/blkid.go new/ignition-2.2.0/internal/exec/util/blkid.go --- old/ignition-2.1.1/internal/exec/util/blkid.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/util/blkid.go 2020-03-23 23:29:56.000000000 +0100 @@ -136,13 +136,13 @@ return DiskInfo{}, err } - numParts := 0 + numParts := C.int(0) cNumPartsRef := (*C.int)(unsafe.Pointer(&numParts)) if err := cResultToErr(C.blkid_get_num_partitions(cDevice, cNumPartsRef), device); err != nil { return DiskInfo{}, err } - for i := 0; i < numParts; i++ { + for i := 0; i < int(numParts); i++ { if err := cResultToErr(C.blkid_get_partition(cDevice, C.int(i), cInfoRef), device); err != nil { return DiskInfo{}, err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/util/passwd.go new/ignition-2.2.0/internal/exec/util/passwd.go --- old/ignition-2.1.1/internal/exec/util/passwd.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/util/passwd.go 2020-03-23 23:29:56.000000000 +0100 @@ -173,11 +173,14 @@ } if distro.WriteAuthorizedKeysFragment() { - writeAuthKeysFile(usr, filepath.Join(usr.HomeDir, ".ssh", "authorized_keys.d", "ignition"), []byte(ks)) + err = writeAuthKeysFile(usr, filepath.Join(usr.HomeDir, ".ssh", "authorized_keys.d", "ignition"), []byte(ks)) } else { - writeAuthKeysFile(usr, filepath.Join(usr.HomeDir, ".ssh", "authorized_keys"), []byte(ks)) + err = writeAuthKeysFile(usr, filepath.Join(usr.HomeDir, ".ssh", "authorized_keys"), []byte(ks)) } + if err != nil { + return fmt.Errorf("failed to set SSH key: %v", err) + } return nil }, "adding ssh keys to user %q", c.Name) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/exec/util/unit.go new/ignition-2.2.0/internal/exec/util/unit.go --- old/ignition-2.1.1/internal/exec/util/unit.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/exec/util/unit.go 2020-03-23 23:29:56.000000000 +0100 @@ -110,8 +110,8 @@ return filepath.Join("/", SystemdUnitsPath(), unit.Name), nil } -func (ut Util) EnableUnit(unit types.Unit) error { - return ut.appendLineToPreset(fmt.Sprintf("enable %s", unit.Name)) +func (ut Util) EnableUnit(enabledUnit string) error { + return ut.appendLineToPreset(fmt.Sprintf("enable %s", enabledUnit)) } // presets link in /etc, which doesn't make sense for runtime units @@ -145,8 +145,8 @@ return ut.WriteLink(link) } -func (ut Util) DisableUnit(unit types.Unit) error { - return ut.appendLineToPreset(fmt.Sprintf("disable %s", unit.Name)) +func (ut Util) DisableUnit(disabledUnit string) error { + return ut.appendLineToPreset(fmt.Sprintf("disable %s", disabledUnit)) } func (ut Util) appendLineToPreset(data string) error { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/platform/platform.go new/ignition-2.2.0/internal/platform/platform.go --- old/ignition-2.1.1/internal/platform/platform.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/platform/platform.go 2020-03-23 23:29:56.000000000 +0100 @@ -24,6 +24,7 @@ "github.com/coreos/ignition/v2/internal/providers/azure" "github.com/coreos/ignition/v2/internal/providers/cloudstack" "github.com/coreos/ignition/v2/internal/providers/digitalocean" + "github.com/coreos/ignition/v2/internal/providers/exoscale" "github.com/coreos/ignition/v2/internal/providers/file" "github.com/coreos/ignition/v2/internal/providers/gcp" "github.com/coreos/ignition/v2/internal/providers/ibmcloud" @@ -33,6 +34,7 @@ "github.com/coreos/ignition/v2/internal/providers/qemu" "github.com/coreos/ignition/v2/internal/providers/virtualbox" "github.com/coreos/ignition/v2/internal/providers/vmware" + "github.com/coreos/ignition/v2/internal/providers/vultr" "github.com/coreos/ignition/v2/internal/providers/zvm" "github.com/coreos/ignition/v2/internal/registry" "github.com/coreos/ignition/v2/internal/resource" @@ -81,10 +83,19 @@ fetch: aliyun.FetchConfig, }) configs.Register(Config{ + name: "aws", + fetch: aws.FetchConfig, + newFetcher: aws.NewFetcher, + }) + configs.Register(Config{ name: "azure", fetch: azure.FetchConfig, }) configs.Register(Config{ + name: "brightbox", + fetch: openstack.FetchConfig, + }) + configs.Register(Config{ name: "cloudstack", fetch: cloudstack.FetchConfig, }) @@ -93,28 +104,39 @@ fetch: digitalocean.FetchConfig, }) configs.Register(Config{ - name: "brightbox", - fetch: openstack.FetchConfig, + name: "exoscale", + fetch: exoscale.FetchConfig, }) configs.Register(Config{ - name: "openstack", - fetch: openstack.FetchConfig, - }) - configs.Register(Config{ - name: "aws", - fetch: aws.FetchConfig, - newFetcher: aws.NewFetcher, + name: "file", + fetch: file.FetchConfig, }) configs.Register(Config{ name: "gcp", fetch: gcp.FetchConfig, }) configs.Register(Config{ + name: "ibmcloud", + fetch: ibmcloud.FetchConfig, + }) + configs.Register(Config{ + name: "metal", + fetch: noop.FetchConfig, + }) + configs.Register(Config{ + name: "openstack", + fetch: openstack.FetchConfig, + }) + configs.Register(Config{ name: "packet", fetch: packet.FetchConfig, status: packet.PostStatus, }) configs.Register(Config{ + name: "qemu", + fetch: qemu.FetchConfig, + }) + configs.Register(Config{ name: "virtualbox", fetch: virtualbox.FetchConfig, }) @@ -123,25 +145,13 @@ fetch: vmware.FetchConfig, }) configs.Register(Config{ - name: "qemu", - fetch: qemu.FetchConfig, - }) - configs.Register(Config{ - name: "file", - fetch: file.FetchConfig, - }) - configs.Register(Config{ - name: "metal", - fetch: noop.FetchConfig, + name: "vultr", + fetch: vultr.FetchConfig, }) configs.Register(Config{ name: "zvm", fetch: zvm.FetchConfig, }) - configs.Register(Config{ - name: "ibmcloud", - fetch: ibmcloud.FetchConfig, - }) } func Get(name string) (config Config, ok bool) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/providers/exoscale/exoscale.go new/ignition-2.2.0/internal/providers/exoscale/exoscale.go --- old/ignition-2.1.1/internal/providers/exoscale/exoscale.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/internal/providers/exoscale/exoscale.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,46 @@ +// Copyright 2020 CoreOS, 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. + +// The Exoscale provider fetches a remote configuration from the +// Exoscale user-data metadata service URL. + +package exoscale + +import ( + "net/url" + + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/providers/util" + "github.com/coreos/ignition/v2/internal/resource" + + "github.com/coreos/vcontext/report" +) + +var ( + userdataURL = url.URL{ + Scheme: "http", + Host: "169.254.169.254", + Path: "1.0/user-data", + } +) + +// FetchConfig fetch Exoscale ign user-data config +func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { + data, err := f.FetchToBuffer(userdataURL, resource.FetchOptions{}) + if err != nil && err != resource.ErrNotFound { + return types.Config{}, report.Report{}, err + } + + return util.ParseConfig(f.Logger, data) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/providers/qemu/qemu.go new/ignition-2.2.0/internal/providers/qemu/qemu.go --- old/ignition-2.1.1/internal/providers/qemu/qemu.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/providers/qemu/qemu.go 1970-01-01 01:00:00.000000000 +0100 @@ -1,51 +0,0 @@ -// Copyright 2016 CoreOS, 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. - -// The QEMU provider fetches a local configuration from the firmware config -// interface (opt/com.coreos/config). - -package qemu - -import ( - "io/ioutil" - "os" - "os/exec" - - "github.com/coreos/ignition/v2/config/v3_1_experimental/types" - "github.com/coreos/ignition/v2/internal/providers/util" - "github.com/coreos/ignition/v2/internal/resource" - - "github.com/coreos/vcontext/report" -) - -const ( - firmwareConfigPath = "/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/config/raw" -) - -func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { - _, err := f.Logger.LogCmd(exec.Command("modprobe", "qemu_fw_cfg"), "loading QEMU firmware config module") - if err != nil { - return types.Config{}, report.Report{}, err - } - - data, err := ioutil.ReadFile(firmwareConfigPath) - if os.IsNotExist(err) { - f.Logger.Info("QEMU firmware config was not found. Ignoring...") - } else if err != nil { - f.Logger.Err("couldn't read QEMU firmware config: %v", err) - return types.Config{}, report.Report{}, err - } - - return util.ParseConfig(f.Logger, data) -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/providers/qemu/qemu_blockdev.go new/ignition-2.2.0/internal/providers/qemu/qemu_blockdev.go --- old/ignition-2.1.1/internal/providers/qemu/qemu_blockdev.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/internal/providers/qemu/qemu_blockdev.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,90 @@ +// 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. + +// +build s390x ppc64le + +// The QEMU provider on s390x and ppc64le fetches a configuration file from an +// attached block device with id 'virtio-ignition'. + +package qemu + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "time" + + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/log" + "github.com/coreos/ignition/v2/internal/providers/util" + "github.com/coreos/ignition/v2/internal/resource" + + "github.com/coreos/vcontext/report" +) + +const ( + ignitionBlockDevicePath = "/dev/disk/by-id/virtio-ignition" + blockDeviceTimeout = 5 * time.Minute + blockDevicePollingInterval = 5 * time.Second +) + +func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { + f.Logger.Warning("Fetching the Ignition config via the Virtio block driver is currently experimental and subject to change.") + + _, err := f.Logger.LogCmd(exec.Command("modprobe", "virtio_blk"), "loading Virtio block driver module") + if err != nil { + return types.Config{}, report.Report{}, err + } + + data, err := fetchConfigFromBlockDevice(f.Logger) + if err != nil { + return types.Config{}, report.Report{}, err + } + + return util.ParseConfig(f.Logger, data) +} + +func fetchConfigFromBlockDevice(logger *log.Logger) ([]byte, error) { + var data []byte + c := make(chan error) + go func() { + var err error + for { + if data, err = ioutil.ReadFile(ignitionBlockDevicePath); err != nil { + if !os.IsNotExist(err) { + break + } + logger.Debug("block device (%q) not found. Waiting...", ignitionBlockDevicePath) + time.Sleep(blockDevicePollingInterval) + } else { + err = nil + break + } + } + c <- err + }() + + select { + case err := <-c: + if err != nil { + return nil, err + } + case <-time.After(blockDeviceTimeout): + return nil, fmt.Errorf("timed out after %v waiting for block device %q to appear", blockDeviceTimeout, ignitionBlockDevicePath) + } + + return bytes.TrimRight(data, "\x00"), nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/providers/qemu/qemu_fwcfg.go new/ignition-2.2.0/internal/providers/qemu/qemu_fwcfg.go --- old/ignition-2.1.1/internal/providers/qemu/qemu_fwcfg.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/internal/providers/qemu/qemu_fwcfg.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,53 @@ +// Copyright 2016 CoreOS, 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. + +// +build amd64 arm64 + +// The QEMU provider on amd64 and arm64 fetches a local configuration from the +// firmware config interface (opt/com.coreos/config). + +package qemu + +import ( + "io/ioutil" + "os" + "os/exec" + + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/providers/util" + "github.com/coreos/ignition/v2/internal/resource" + + "github.com/coreos/vcontext/report" +) + +const ( + firmwareConfigPath = "/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/config/raw" +) + +func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { + _, err := f.Logger.LogCmd(exec.Command("modprobe", "qemu_fw_cfg"), "loading QEMU firmware config module") + if err != nil { + return types.Config{}, report.Report{}, err + } + + data, err := ioutil.ReadFile(firmwareConfigPath) + if os.IsNotExist(err) { + f.Logger.Info("QEMU firmware config was not found. Ignoring...") + } else if err != nil { + f.Logger.Err("couldn't read QEMU firmware config: %v", err) + return types.Config{}, report.Report{}, err + } + + return util.ParseConfig(f.Logger, data) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/providers/vultr/vultr.go new/ignition-2.2.0/internal/providers/vultr/vultr.go --- old/ignition-2.1.1/internal/providers/vultr/vultr.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/internal/providers/vultr/vultr.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,46 @@ +// Copyright 2020 Red Hat +// +// 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. + +// The vultr provider fetches a remote configuration from the vultr +// user-data metadata service URL. +// https://web.archive.org/web/20190513194756/https://www.vultr.com/metadata/#user + +package vultr + +import ( + "net/url" + + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/providers/util" + "github.com/coreos/ignition/v2/internal/resource" + + "github.com/coreos/vcontext/report" +) + +var ( + userdataUrl = url.URL{ + Scheme: "http", + Host: "169.254.169.254", + Path: "user-data/user-data", + } +) + +func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { + data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{}) + if err != nil && err != resource.ErrNotFound { + return types.Config{}, report.Report{}, err + } + + return util.ParseConfig(f.Logger, data) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/internal/systemd/systemd.go new/ignition-2.2.0/internal/systemd/systemd.go --- old/ignition-2.1.1/internal/systemd/systemd.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/internal/systemd/systemd.go 2020-03-23 23:29:56.000000000 +0100 @@ -16,6 +16,8 @@ import ( "fmt" + "regexp" + "strconv" "github.com/coreos/go-systemd/dbus" "github.com/coreos/go-systemd/unit" @@ -48,3 +50,27 @@ return nil } + +// GetSystemdVersion fetches the version of Systemd +// in a given system. +func GetSystemdVersion() (uint, error) { + conn, err := dbus.NewSystemdConnection() + if err != nil { + return 0, err + } + version, err := conn.GetManagerProperty("Version") + if err != nil { + return 0, err + } + // Handle different systemd versioning schemes that are being returned. + // for e.g: + // - Fedora 31: `"v243.5-1.fc31"` + // - RHEL 8: `"239"` + re := regexp.MustCompile(`\d+`) + systemdVersion := re.FindString(version) + value, err := strconv.Atoi(systemdVersion) + if err != nil { + return 0, err + } + return uint(value), nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/tests/filesystem.go new/ignition-2.2.0/tests/filesystem.go --- old/ignition-2.1.1/tests/filesystem.go 2019-12-13 23:06:16.000000000 +0100 +++ new/ignition-2.2.0/tests/filesystem.go 2020-03-23 23:29:56.000000000 +0100 @@ -155,7 +155,9 @@ cmd.Dir = cwd cmd.Env = append(os.Environ(), appendEnv...) out, err := cmd.CombinedOutput() - t.Logf("PID: %d", cmd.Process.Pid) + if cmd != nil && cmd.Process != nil { + t.Logf("PID: %d", cmd.Process.Pid) + } t.Logf("Ignition output:\n%s", string(out)) if strings.Contains(string(out), "panic") { return fmt.Errorf("ignition panicked") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ignition-2.1.1/tests/positive/files/units.go new/ignition-2.2.0/tests/positive/files/units.go --- old/ignition-2.1.1/tests/positive/files/units.go 1970-01-01 01:00:00.000000000 +0100 +++ new/ignition-2.2.0/tests/positive/files/units.go 2020-03-23 23:29:56.000000000 +0100 @@ -0,0 +1,74 @@ +// Copyright 2020 CoreOS, 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 files + +import ( + "github.com/coreos/ignition/v2/tests/register" + "github.com/coreos/ignition/v2/tests/types" +) + +func init() { + register.Register(register.PositiveTest, CreateInstantiatedService()) +} + +func CreateInstantiatedService() types.Test { + name := "instantiated.unit.create" + in := types.GetBaseDisk() + out := types.GetBaseDisk() + config := `{ + "ignition": { "version": "$version" }, + "systemd": { + "units": [ + { + "name": "[email protected]", + "contents": "[Unit]\nDescription=f\n[Service]\nType=oneshot\nExecStart=/bin/echo %i\nRemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target\n" + }, + { + "enabled": true, + "name": "[email protected]" + }, + { + "enabled": true, + "name": "[email protected]" + } + ] + } + }` + configMinVersion := "3.0.0" + out[0].Partitions.AddFiles("ROOT", []types.File{ + { + Node: types.Node{ + Name: "[email protected]", + Directory: "etc/systemd/system", + }, + Contents: "[Unit]\nDescription=f\n[Service]\nType=oneshot\nExecStart=/bin/echo %i\nRemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target\n", + }, + { + Node: types.Node{ + Name: "20-ignition.preset", + Directory: "etc/systemd/system-preset", + }, + Contents: "enable [email protected] bar foo\n", + }, + }) + + return types.Test{ + Name: name, + In: in, + Out: out, + Config: config, + ConfigMinVersion: configMinVersion, + } +}
