Hello community,

here is the log from the commit of package ignition for openSUSE:Factory 
checked in at 2019-12-23 22:47:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ignition (Old)
 and      /work/SRC/openSUSE:Factory/.ignition.new.6675 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ignition"

Mon Dec 23 22:47:40 2019 rev:8 rq:758999 version:2.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/ignition/ignition.changes        2019-11-20 
12:38:23.037783832 +0100
+++ /work/SRC/openSUSE:Factory/.ignition.new.6675/ignition.changes      
2019-12-23 22:49:13.370107054 +0100
@@ -1,0 +2,21 @@
+Mon Dec 23 09:16:22 UTC 2019 - [email protected]
+
+- Update to version 2.1.1:
+  * stages/files: don't relabel /home and /root symlinks
+  * tests/filesystems: fix error handling
+  * blackbox tests: don't swallow errors
+  * log: use os.ProcessState.ExitCode instead of unix
+  * travis: bump min go to 1.12
+  * news: add notes for 2.1.1
+  * readme: fix links, add validation container docs
+  * Dockerfile: add dockerfile for ignition-validate
+  * news: add news for v2.1.0
+  * README.md: add details about dracut and branches here
+  * doc/operator-notes: simplify SELinux section
+  * mount: also relabel mount points
+  * util: factor out FindFirstMissingDirForFile function
+  * files: perform relabeling from initrd
+  * doc/examples: Make example file path valid
+  * Rework fetch/resource to automatically append required headers
+
+-------------------------------------------------------------------

Old:
----
  ignition-2.0.1+git20191112.a924dd7.tar.xz

New:
----
  ignition-2.1.1.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ignition.spec ++++++
--- /var/tmp/diff_new_pack.NcIjni/_old  2019-12-23 22:49:14.154107344 +0100
+++ /var/tmp/diff_new_pack.NcIjni/_new  2019-12-23 22:49:14.154107344 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ignition
 #
-# Copyright (c) 2019 SUSE LLC.
+# Copyright (c) 2019 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           ignition
-Version:        2.0.1+git20191112.a924dd7
+Version:        2.1.1
 Release:        0
 Summary:        First boot installer and configuration tool
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.NcIjni/_old  2019-12-23 22:49:14.186107356 +0100
+++ /var/tmp/diff_new_pack.NcIjni/_new  2019-12-23 22:49:14.190107357 +0100
@@ -1,7 +1,7 @@
 <services>
   <service name="tar_scm" mode="disabled">
-    <param name="version">2.0.1</param>
-    <param name="versionformat">2.0.1+git%cd.%h</param>
+    <param name="version">2.1.1</param>
+    <param name="revision">v2.1.1</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.NcIjni/_old  2019-12-23 22:49:14.202107361 +0100
+++ /var/tmp/diff_new_pack.NcIjni/_new  2019-12-23 22:49:14.206107363 +0100
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">git://github.com/coreos/ignition.git</param>
-    <param 
name="changesrevision">a924dd7d11685a30bf79f20ce9fc3ca93860f032</param>
+    <param 
name="changesrevision">40c0b57b7606bd23210059c5554f151776a1d64b</param>
  </service>
 </servicedata>
\ No newline at end of file

++++++ ignition-2.0.1+git20191112.a924dd7.tar.xz -> ignition-2.1.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20191112.a924dd7/.travis.yml 
new/ignition-2.1.1/.travis.yml
--- old/ignition-2.0.1+git20191112.a924dd7/.travis.yml  2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/.travis.yml      2019-12-13 23:06:16.000000000 +0100
@@ -3,7 +3,7 @@
 go_import_path: github.com/coreos/ignition/v2
 
 go:
-  - "1.11.x"
+  - "1.12.x"
   - "1.13.x"
 
 arch:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/Dockerfile.validate 
new/ignition-2.1.1/Dockerfile.validate
--- old/ignition-2.0.1+git20191112.a924dd7/Dockerfile.validate  1970-01-01 
01:00:00.000000000 +0100
+++ new/ignition-2.1.1/Dockerfile.validate      2019-12-13 23:06:16.000000000 
+0100
@@ -0,0 +1,9 @@
+FROM golang:latest AS builder
+RUN mkdir /ignition-validate
+COPY . /ignition-validate
+WORKDIR /ignition-validate
+RUN ./build_releases
+
+FROM scratch
+COPY --from=builder 
/ignition-validate/bin/releases/ignition-validate-x86_64-unknown-linux-gnu 
/usr/local/bin/ignition-validate
+ENTRYPOINT ["/usr/local/bin/ignition-validate"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20191112.a924dd7/NEWS 
new/ignition-2.1.1/NEWS
--- old/ignition-2.0.1+git20191112.a924dd7/NEWS 2019-11-12 17:46:21.000000000 
+0100
+++ new/ignition-2.1.1/NEWS     2019-12-13 23:06:16.000000000 +0100
@@ -1,3 +1,45 @@
+13-Dec-2019 Ignition 2.1.1
+
+  Bug Fixes:
+
+    - Fix panics when processes Ignition starts fail
+
+  Features:
+
+    - An ignition-validate container is now built and can be used instead of
+      the ignition-validate binaries
+
+12-Dec-2019 Ignition 2.1.0
+
+  Bug Fixes:
+
+    - Do not panic when filesystem paths are unspecified
+    - Specify the correct config version HTTP Accept headers when fetching
+      configs
+    - Write the config cache file atomically
+    - Relabel symlinks for masking systemd units
+    - Fix bug where empty GPT labels were treated as errors
+    - Do not generate warnings if mode is unset for files with only an append
+      section
+    - Validate HTTP(S) proxy urls in spec 3.1.0-experimental
+
+  Features:
+
+    - Ignition now logs the name of the stage it is running
+    - Ignition now relabels files directly instead of writing systemd units to
+      do so. Requires Linux 5.4.0+ or a patch. See operator notes for more
+      details
+    - Add optional "fetch" stage to cache the rendered config, but not apply
+      any of it
+    - Add support for aliyun cloud
+    - Add support for zVM hypervisor
+    - Add support for specifying mount options for filesystems in spec
+      3.1.0-experimental
+
+  Dependency Changes:
+
+    - Ignition no longer needs the chroot or id binaries in the initramfs
+
 24-Jul-2019 Ignition 2.0.1
 
   Bug Fixes:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20191112.a924dd7/README.md 
new/ignition-2.1.1/README.md
--- old/ignition-2.0.1+git20191112.a924dd7/README.md    2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/README.md        2019-12-13 23:06:16.000000000 +0100
@@ -1,8 +1,6 @@
 # Ignition
 
-Ignition is the utility used by CoreOS Container Linux to manipulate disks 
during the initramfs. This includes partitioning disks, formatting partitions, 
writing files (regular files, systemd units, etc.), and configuring users. On 
first boot, Ignition reads its configuration from a source of truth (remote 
URL, network metadata service, hypervisor bridge, etc.) and applies the 
configuration.
-
-Ignition has two main development branches: master and spec2x. This is the 
master branch which is for Ignition included in Red Hat CoreOS and Fedora 
CoreOS. For Ignition development for Container Linux see the 
[spec2x](https://github.com/coreos/ignition/tree/spec2x) branch.
+Ignition is the utility used by CoreOS Container Linux, Fedora CoreOS, and 
RHEL CoreOS to manipulate disks during the initramfs. This includes 
partitioning disks, formatting partitions, writing files (regular files, 
systemd units, etc.), and configuring users. On first boot, Ignition reads its 
configuration from a source of truth (remote URL, network metadata service, 
hypervisor bridge, etc.) and applies the configuration.
 
 ## Usage
 
@@ -10,8 +8,8 @@
 
 ## Contact
 
-- Mailing list: 
[coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev)
-- IRC: #[coreos](irc://irc.freenode.org:6697/#coreos) on freenode.org
+- Mailing list: 
[[email protected]](https://lists.fedoraproject.org/archives/list/[email protected]/)
+- IRC: #[fedora-coreos](irc://irc.freenode.org:6697/#fedora-coreos) on 
freenode.org
 - Bugs: [issues][issues]
 
 ## Contributing
@@ -26,7 +24,32 @@
 
 ## Config Validation
 
-To validate a config for Ignition there are binaries for a cli tool called 
ignition-validate available [on the releases page][releases], and an online 
validator available [on the CoreOS website][online-validator].
+To validate a config for Ignition there are binaries for a cli tool called 
`ignition-validate` available [on the releases page][releases]. There is also 
an ignition-validate container: `quay.io/coreos/ignition-validate`.
+
+Example:
+```
+# This example uses podman, but docker can be used too
+podman run --rm -i quay.io/coreos/ignition-validate - < myconfig.ign
+```
+
+## Dracut
+
+For distributions that use dracut, there is an
+[ignition-dracut](https://github.com/coreos/ignition-dracut)
+repo which contains scripts and systemd units for boot-time
+execution. But it's very likely that distributions will have
+to do additional work in order to properly integrate with
+Ignition.
+
+## Branches
+
+There are two branches:
+- `master` works with the `master` branch of ignition-dracut
+  and is currently used by Fedora CoreOS, which targets
+  Ignition v2 (spec 3).
+- `spec2x` works with the `spec2x` branch of ignition-dracut
+  and is currently used by CL and RHEL CoreOS, which (for
+  now) targets Ignition v0.x (spec 2).
 
 [getting started]: doc/getting-started.md
 [issues]:  https://github.com/coreos/ignition/issues/new/choose
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20191112.a924dd7/doc/examples.md 
new/ignition-2.1.1/doc/examples.md
--- old/ignition-2.0.1+git20191112.a924dd7/doc/examples.md      2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/doc/examples.md  2019-12-13 23:06:16.000000000 +0100
@@ -59,14 +59,14 @@
 ```
 ## Create Files on the Root Filesystem
 
-In many cases it is useful to write files to the root filesystem. This example 
writes a single file to `/foo/bar` on the root filesystem. The contents of the 
file ("example file") are specified inline in the config using the [data URL 
scheme][rfc2397].
+In many cases it is useful to write files to the root filesystem. This example 
writes a single file to `/etc/someconfig` on the root filesystem. The contents 
of the file ("example file") are specified inline in the config using the [data 
URL scheme][rfc2397].
 
 ```json ignition
 {
   "ignition": { "version": "3.0.0" },
   "storage": {
     "files": [{
-      "path": "/foo/bar",
+      "path": "/etc/someconfig",
       "mode": 420,
       "contents": { "source": "data:,example%20file%0A" }
     }]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/doc/operator-notes.md 
new/ignition-2.1.1/doc/operator-notes.md
--- old/ignition-2.0.1+git20191112.a924dd7/doc/operator-notes.md        
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/doc/operator-notes.md    2019-12-13 23:06:16.000000000 
+0100
@@ -37,35 +37,10 @@
 
 ## SELinux
 
-When using Ignition with distributions which have [SELinux][selinux] enabled, 
extra care must be taken to prevent Ignition from creating files that lack 
SELinux labels. Unfortunately, distributions do not typically include SELinux 
policies in the initramfs where Ignition runs, so any files, directories, and 
links created by Ignition don't receive the proper default SELinux labels.
-
-A workaround for this issue is to use [`restorecon`][restorecon] in a oneshot 
systemd unit to relabel files that Ignition has touched. This unit can be set 
to run after the SELinux policies have loaded, but before services will try to 
use them.
-
-An example of this unit is as follows:
-
-```
-[Unit]
-Requires=systemd-udevd.target
-After=systemd-udevd.target
-
-Before=sssd.service
-DefaultDependencies=no
-ConditionFirstBoot=true
-
-[Service]
-Type=oneshot
-ExecStart=/usr/sbin/restorecon /foo/bar /etc/test 
/etc/systemd/system/example.service /etc/passwd /etc/group /etc/shadow
-
-[Install]
-WantedBy=multi-user.target
-```
-
-This unit will vary based on the Ignition config it is being added to and the 
distribution that Ignition is running on. Notably the paths listed in the unit 
are all paths that Ignition caused to be modified or created, not just paths 
listed in `storage.files`. For example, if a new user is created then 
`/etc/passwd`, `/etc/shadow`, and `/etc/group` will all need to be relabeled.
-
-If tooling is being used to generate Ignition configs, the tooling _should_ 
generate such a unit when creating a config for distributions which rely on 
SELinux.
+Ignition fully supports distributions which have [SELinux][selinux] enabled. 
It requires that the distribution ships the [`setfiles`][setfiles] utility. The 
kernel must be at least v5.5 or alternatively have [this 
patch](https://lore.kernel.org/selinux/[email protected]/T/#u)
 backported.
 
 [selinux]: https://selinuxproject.org/page/Main_Page
-[restorecon]: https://linux.die.net/man/8/restorecon
+[setfiles]: https://linux.die.net/man/8/setfiles
 
 ## Partition Reuse Semantics
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/distro/distro.go 
new/ignition-2.1.1/internal/distro/distro.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/distro/distro.go    
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/distro/distro.go        2019-12-13 
23:06:16.000000000 +0100
@@ -41,10 +41,7 @@
        udevadmCmd  = "udevadm"
        usermodCmd  = "usermod"
        useraddCmd  = "useradd"
-
-       // The restorecon tool is embedded inside of a systemd unit
-       // and as such requires the absolute path
-       restoreconCmd = "/usr/sbin/restorecon"
+       setfilesCmd = "setfiles"
 
        // Filesystem tools
        btrfsMkfsCmd = "mkfs.btrfs"
@@ -75,15 +72,15 @@
 func KernelCmdlinePath() string { return kernelCmdlinePath }
 func SystemConfigDir() string   { return fromEnv("SYSTEM_CONFIG_DIR", 
systemConfigDir) }
 
-func GroupaddCmd() string   { return groupaddCmd }
-func MdadmCmd() string      { return mdadmCmd }
-func MountCmd() string      { return mountCmd }
-func SgdiskCmd() string     { return sgdiskCmd }
-func ModprobeCmd() string   { return modprobeCmd }
-func UdevadmCmd() string    { return udevadmCmd }
-func UsermodCmd() string    { return usermodCmd }
-func UseraddCmd() string    { return useraddCmd }
-func RestoreconCmd() string { return restoreconCmd }
+func GroupaddCmd() string { return groupaddCmd }
+func MdadmCmd() string    { return mdadmCmd }
+func MountCmd() string    { return mountCmd }
+func SgdiskCmd() string   { return sgdiskCmd }
+func ModprobeCmd() string { return modprobeCmd }
+func UdevadmCmd() string  { return udevadmCmd }
+func UsermodCmd() string  { return usermodCmd }
+func UseraddCmd() string  { return useraddCmd }
+func SetfilesCmd() string { return setfilesCmd }
 
 func BtrfsMkfsCmd() string { return btrfsMkfsCmd }
 func Ext4MkfsCmd() string  { return ext4MkfsCmd }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/engine.go 
new/ignition-2.1.1/internal/exec/engine.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/exec/engine.go      
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/engine.go  2019-12-13 23:06:16.000000000 
+0100
@@ -272,9 +272,7 @@
        if err != nil {
                return types.Config{}, err
        }
-       rawCfg, err := e.Fetcher.FetchToBuffer(*u, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       rawCfg, err := e.Fetcher.FetchToBuffer(*u, resource.FetchOptions{})
        if err != nil {
                return types.Config{}, err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/files/files.go 
new/ignition-2.1.1/internal/exec/stages/files/files.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/files/files.go  
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/stages/files/files.go      2019-12-13 
23:06:16.000000000 +0100
@@ -17,10 +17,7 @@
 import (
        "errors"
        "fmt"
-       "io/ioutil"
-       "os"
        "path/filepath"
-       "strings"
 
        "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
        "github.com/coreos/ignition/v2/internal/distro"
@@ -32,9 +29,6 @@
 
 const (
        name = "files"
-
-       // see 
https://github.com/systemd/systemd/commit/65e183d7899eb3725d3009196ac4decf1090b580
-       relabelExtraDir = "/run/systemd/relabel-extra.d"
 )
 
 var (
@@ -87,17 +81,8 @@
                return fmt.Errorf("failed to create units: %v", err)
        }
 
-       // add systemd unit to relabel files
-       if err := s.addRelabelUnit(); err != nil {
-               return fmt.Errorf("failed to add relabel unit: %v", err)
-       }
-
-       // Add a file in /run/systemd/relabel-extra.d/ with paths that need to 
be relabeled
-       // as early as possible (e.g. systemd units so systemd can read them 
while building its
-       // graph). These are relabeled very early (right after policy load) so 
it cannot relabel
-       // across mounts. Only relabel things in /etc here.
-       if err := s.addRelabelExtraFile(); err != nil {
-               return fmt.Errorf("failed to write systemd relabel file: %v", 
err)
+       if err := s.relabelFiles(); err != nil {
+               return fmt.Errorf("failed to handle relabeling: %v", err)
        }
 
        return nil
@@ -106,23 +91,11 @@
 // checkRelabeling determines whether relabeling is supported/requested so that
 // we only collect filenames if we need to.
 func (s *stage) checkRelabeling() error {
-       if !distro.SelinuxRelabel() || distro.RestoreconCmd() == "" {
+       if !distro.SelinuxRelabel() {
                s.Logger.Debug("compiled without relabeling support, skipping")
                return nil
        }
 
-       path, err := s.JoinPath(distro.RestoreconCmd())
-       if err != nil {
-               return fmt.Errorf("error resolving path for %s: %v", 
distro.RestoreconCmd(), err)
-       }
-
-       _, err = os.Lstat(path)
-       if err != nil && os.IsNotExist(err) {
-               return fmt.Errorf("targeting root without %s, cannot relabel", 
distro.RestoreconCmd())
-       } else if err != nil {
-               return fmt.Errorf("error checking for %s in root: %v", 
distro.RestoreconCmd(), err)
-       }
-
        // initialize to non-nil (whereas a nil slice means not to append, even
        // though they're functionally equivalent)
        s.toRelabel = []string{}
@@ -137,82 +110,24 @@
 // relabel adds one or more paths to the list of paths that need relabeling.
 func (s *stage) relabel(paths ...string) {
        if s.toRelabel != nil {
-               s.toRelabel = append(s.toRelabel, paths...)
+               for _, path := range paths {
+                       s.toRelabel = append(s.toRelabel, 
filepath.Join(s.DestDir, path))
+               }
        }
 }
 
-// addRelabelUnit creates and enables a runtime systemd unit to run restorecon
-// if there are files that need to be relabeled.
-func (s *stage) addRelabelUnit() error {
-       if len(s.toRelabel) == 0 {
+// relabelFiles relabels all the files that were marked for relabeling using
+// the libselinux APIs.
+func (s *stage) relabelFiles() error {
+       if s.toRelabel == nil || len(s.toRelabel) == 0 {
                return nil
        }
-       contents := `[Unit]
-Description=Relabel files created by Ignition
-DefaultDependencies=no
-After=local-fs.target
-Before=sysinit.target systemd-sysctl.service
-ConditionSecurity=selinux
-ConditionPathExists=/etc/selinux/ignition.relabel
-OnFailure=emergency.target
-OnFailureJobMode=replace-irreversibly
-
-[Service]
-Type=oneshot
-ExecStart=` + distro.RestoreconCmd() + ` -0vRif /etc/selinux/ignition.relabel
-ExecStart=/usr/bin/rm /etc/selinux/ignition.relabel
-RemainAfterExit=yes`
-
-       // create the unit file itself
-       unit := types.Unit{
-               Name:     "ignition-relabel.service",
-               Contents: &contents,
-       }
-
-       if err := s.writeSystemdUnit(unit, true); err != nil {
-               return err
-       }
-
-       if err := s.EnableRuntimeUnit(unit, "sysinit.target"); err != nil {
-               return err
-       }
-
-       // and now create the list of files to relabel
-       etcRelabelPath, err := s.JoinPath("etc/selinux/ignition.relabel")
-       if err != nil {
-               return err
-       }
-       f, err := os.Create(etcRelabelPath)
-       if err != nil {
-               return err
-       }
-       defer f.Close()
-
-       // yes, apparently the final \0 is needed
-       _, err = f.WriteString(strings.Join(s.toRelabel, "\000") + "\000")
-       return err
-}
-
-// addRelabelExtraFile writes a file to /run/systemd/relabel-extra.d/ with a 
list of files
-// that should be relabeled immediately after policy load. In our case that's 
everything we
-// wrote under /etc. This ensures systemd can access the files when building 
it's graph.
-func (s stage) addRelabelExtraFile() error {
-       relabelFilePath := filepath.Join(relabelExtraDir, "ignition.relabel")
-       s.Logger.Info("adding relabel-extra.d/ file: %q", relabelFilePath)
-       defer s.Logger.Info("finished adding relabel file")
-
-       relabelFileContents := ""
-       for _, file := range s.toRelabel {
-               if strings.HasPrefix(file, "/etc") {
-                       relabelFileContents += file + "\n"
-               }
-       }
-       if relabelFileContents == "" {
-               return nil
-       }
-       if err := os.MkdirAll(relabelExtraDir, 0755); err != nil {
-               return err
-       }
 
-       return ioutil.WriteFile(relabelFilePath, []byte(relabelFileContents), 
0644)
+       // We could go further here and use the `setfscreatecon` API so that we
+       // atomically create the files from the start with the right label, but 
(1)
+       // atomicity isn't really necessary here since there is not even a 
policy
+       // loaded and hence no MAC enforced, and (2) we'd still need 
after-the-fact
+       // labeling for files created by processes we call out to, like 
`useradd`.
+
+       return s.RelabelFiles(s.toRelabel)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/files/filesystemEntries.go
 new/ignition-2.1.1/internal/exec/stages/files/filesystemEntries.go
--- 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/files/filesystemEntries.go
      2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/stages/files/filesystemEntries.go  
2019-12-13 23:06:16.000000000 +0100
@@ -254,31 +254,14 @@
        if !s.relabeling() {
                return nil
        }
-       // relabel from the first parent dir that we'll have to create --
-       // alternatively, we could make `MkdirForFile` fancier instead of
-       // using `os.MkdirAll`, though that's quite a lot of levels to plumb
-       // through
-       relabelFrom := path
-       dir := filepath.Dir(path)
-       for {
-               exists := true
-               if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
-                       exists = false
-               } else if err != nil {
-                       return err
-               }
 
-               // we're done on the first hit -- also sanity check we didn't
-               // somehow get all the way up to /sysroot
-               if exists || dir == s.DestDir {
-                       break
-               }
-               relabelFrom = dir
-               dir = filepath.Dir(dir)
+       missing_dir, err := util.FindFirstMissingDirForFile(path)
+       if err != nil {
+               return err
        }
-       // trim off prefix since this needs to be relative to the sysroot
-       s.relabel(relabelFrom[len(s.DestDir):])
 
+       // trim off prefix since this needs to be relative to the sysroot
+       s.relabel(missing_dir[len(s.DestDir):])
        return nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/mount/mount.go 
new/ignition-2.1.1/internal/exec/stages/mount/mount.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/exec/stages/mount/mount.go  
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/stages/mount/mount.go      2019-12-13 
23:06:16.000000000 +0100
@@ -111,6 +111,15 @@
                return err
        }
 
+       var firstMissing string
+       if distro.SelinuxRelabel() {
+               var err error
+               firstMissing, err = util.FindFirstMissingDirForFile(path)
+               if err != nil {
+                       return err
+               }
+       }
+
        if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
                if err := os.MkdirAll(path, 0755); err != nil {
                        return err
@@ -119,6 +128,12 @@
                return err
        }
 
+       if distro.SelinuxRelabel() {
+               if err := s.RelabelFiles([]string{firstMissing}); err != nil {
+                       return err
+               }
+       }
+
        args := translateOptionSliceToString(fs.MountOptions, ",")
        cmd := exec.Command(distro.MountCmd(), "-o", args, "-t", *fs.Format, 
fs.Device, path)
        if _, err := s.Logger.LogCmd(cmd,
@@ -126,6 +141,18 @@
        ); err != nil {
                return err
        }
+
+       if distro.SelinuxRelabel() {
+               // relabel the root of the disk if it's fresh
+               if isEmpty, err := util.DirIsEmpty(path); err != nil {
+                       return fmt.Errorf("Checking if directory %s is empty: 
%v", path, err)
+               } else if isEmpty {
+                       if err := s.RelabelFiles([]string{path}); err != nil {
+                               return err
+                       }
+               }
+       }
+
        return nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/util/file.go 
new/ignition-2.1.1/internal/exec/util/file.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/exec/util/file.go   
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/util/file.go       2019-12-13 
23:06:16.000000000 +0100
@@ -242,6 +242,47 @@
        return os.MkdirAll(filepath.Dir(path), DefaultDirectoryPermissions)
 }
 
+// FindFirstMissingDirForFile returns the first component which was found to be
+// missing for the path.
+func FindFirstMissingDirForFile(path string) (string, error) {
+       entry := path
+       dir := filepath.Dir(path)
+       for {
+               exists := true
+               if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
+                       exists = false
+               } else if err != nil {
+                       return "", err
+               }
+
+               // also sanity check we didn't somehow get all the way up to 
/sysroot
+               if dir == "/" {
+                       return "", fmt.Errorf("/ doesn't seem to exist")
+               }
+               if exists {
+                       return entry, nil
+               }
+               entry = dir
+               dir = filepath.Dir(dir)
+       }
+}
+
+// DirIsEmpty checks whether a directory is empty.
+// Adapted from https://stackoverflow.com/a/30708914
+func DirIsEmpty(dirpath string) (bool, error) {
+       dfd, err := os.Open(dirpath)
+       if err != nil {
+               return false, err
+       }
+       defer dfd.Close()
+
+       _, err = dfd.Readdirnames(1)
+       if err == io.EOF {
+               return true, nil
+       }
+       return false, err
+}
+
 // getFileOwner will return the uid and gid for the file at a given path. If 
the
 // file doesn't exist, or some other error is encountered when running stat on
 // the path, 0, 0, and 0 will be returned.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/exec/util/selinux.go 
new/ignition-2.1.1/internal/exec/util/selinux.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/exec/util/selinux.go        
1970-01-01 01:00:00.000000000 +0100
+++ new/ignition-2.1.1/internal/exec/util/selinux.go    2019-12-13 
23:06:16.000000000 +0100
@@ -0,0 +1,86 @@
+// Copyright 2019 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 util
+
+import (
+       "bufio"
+       "fmt"
+       "os"
+       "os/exec"
+       "strings"
+
+       "github.com/coreos/ignition/v2/internal/distro"
+)
+
+const (
+       selinuxConfig       = "/etc/selinux/config"
+       selinuxFileContexts = "contexts/files/file_contexts"
+)
+
+var selinuxPolicy = ""
+
+func (ut Util) getSelinuxPolicy() (string, error) {
+       if selinuxPolicy == "" {
+               configPath, err := ut.JoinPath(selinuxConfig)
+               if err != nil {
+                       return "", err
+               }
+
+               file, err := os.Open(configPath)
+               if err != nil {
+                       return "", fmt.Errorf("failed to open %v: %v", 
selinuxConfig, err)
+               }
+               defer file.Close()
+
+               scanner := bufio.NewScanner(file)
+               for scanner.Scan() {
+                       line := strings.TrimSpace(scanner.Text())
+                       if strings.HasPrefix(line, "SELINUXTYPE=") {
+                               policy := line[len("SELINUXTYPE="):]
+                               if len(policy) == 0 {
+                                       return "", fmt.Errorf("invalid 
SELINUXTYPE value in %v", selinuxConfig)
+                               }
+                               selinuxPolicy = policy
+                               break
+                       }
+               }
+
+               if selinuxPolicy == "" {
+                       return "", fmt.Errorf("didn't find SELINUXTYPE in %v", 
selinuxConfig)
+               }
+       }
+
+       return selinuxPolicy, nil
+}
+
+// RelabelFiles relabels all the files matching the globby patterns given.
+func (ut Util) RelabelFiles(patterns []string) error {
+       policy, err := ut.getSelinuxPolicy()
+       if err != nil {
+               return err
+       }
+
+       file_contexts, err := ut.JoinPath("/etc/selinux", policy, 
selinuxFileContexts)
+       if err != nil {
+               return err
+       }
+
+       cmd := exec.Command(distro.SetfilesCmd(), "-vFi0", "-r", ut.DestDir, 
file_contexts, "-f", "-")
+       cmd.Stdin = strings.NewReader(strings.Join(patterns, "\000") + "\000")
+       if _, err := ut.Logger.LogCmd(cmd, "relabeling %d patterns", 
len(patterns)); err != nil {
+               return err
+       }
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/log/log.go 
new/ignition-2.1.1/internal/log/log.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/log/log.go  2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/log/log.go      2019-12-13 23:06:16.000000000 
+0100
@@ -20,8 +20,6 @@
        "log/syslog"
        "os/exec"
        "strings"
-
-       "golang.org/x/sys/unix"
 )
 
 type LoggerOps interface {
@@ -150,7 +148,7 @@
                cmd.Stderr = stderr
                if err := cmd.Run(); err != nil {
                        if exitErr, ok := err.(*exec.ExitError); ok {
-                               code = 
exitErr.Sys().(unix.WaitStatus).ExitStatus()
+                               code = exitErr.ExitCode()
                        }
                        return fmt.Errorf("%v: Cmd: %s Stdout: %q Stderr: %q", 
err, cmdLine, stdout.Bytes(), stderr.Bytes())
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/aliyun/aliyun.go 
new/ignition-2.1.1/internal/providers/aliyun/aliyun.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/providers/aliyun/aliyun.go  
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/aliyun/aliyun.go      2019-12-13 
23:06:16.000000000 +0100
@@ -36,9 +36,7 @@
 )
 
 func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
-       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{})
        if err != nil && err != resource.ErrNotFound {
                return types.Config{}, report.Report{}, err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/aws/aws.go 
new/ignition-2.1.1/internal/providers/aws/aws.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/providers/aws/aws.go        
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/aws/aws.go    2019-12-13 
23:06:16.000000000 +0100
@@ -41,9 +41,7 @@
 )
 
 func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
-       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{})
        if err != nil && err != resource.ErrNotFound {
                return types.Config{}, report.Report{}, err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/cloudstack/cloudstack.go
 new/ignition-2.1.1/internal/providers/cloudstack/cloudstack.go
--- 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/cloudstack/cloudstack.go
  2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/cloudstack/cloudstack.go      
2019-12-13 23:06:16.000000000 +0100
@@ -204,8 +204,6 @@
                Path:   "/latest/user-data",
        }
 
-       res, err := f.FetchToBuffer(metadataServiceUrl, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       res, err := f.FetchToBuffer(metadataServiceUrl, resource.FetchOptions{})
        return res, err
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/cmdline/cmdline.go 
new/ignition-2.1.1/internal/providers/cmdline/cmdline.go
--- 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/cmdline/cmdline.go    
    2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/cmdline/cmdline.go    2019-12-13 
23:06:16.000000000 +0100
@@ -46,9 +46,7 @@
                return types.Config{}, report.Report{}, providers.ErrNoProvider
        }
 
-       data, err := f.FetchToBuffer(*url, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       data, err := f.FetchToBuffer(*url, resource.FetchOptions{})
        if err != nil {
                return types.Config{}, report.Report{}, err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/digitalocean/digitalocean.go
 new/ignition-2.1.1/internal/providers/digitalocean/digitalocean.go
--- 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/digitalocean/digitalocean.go
      2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/digitalocean/digitalocean.go  
2019-12-13 23:06:16.000000000 +0100
@@ -36,9 +36,7 @@
 )
 
 func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
-       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{})
        if err != nil {
                return types.Config{}, report.Report{}, err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/gcp/gcp.go 
new/ignition-2.1.1/internal/providers/gcp/gcp.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/providers/gcp/gcp.go        
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/gcp/gcp.go    2019-12-13 
23:06:16.000000000 +0100
@@ -18,6 +18,7 @@
 package gcp
 
 import (
+       "net/http"
        "net/url"
 
        "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
@@ -38,7 +39,7 @@
 )
 
 func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
-       headers := resource.ConfigHeaders
+       headers := make(http.Header)
        headers.Set(metadataHeaderKey, metadataHeaderVal)
        data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
                Headers: headers,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/openstack/openstack.go
 new/ignition-2.1.1/internal/providers/openstack/openstack.go
--- 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/openstack/openstack.go
    2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/openstack/openstack.go        
2019-12-13 23:06:16.000000000 +0100
@@ -131,8 +131,6 @@
 }
 
 func fetchConfigFromMetadataService(f *resource.Fetcher) ([]byte, error) {
-       res, err := f.FetchToBuffer(metadataServiceUrl, resource.FetchOptions{
-               Headers: resource.ConfigHeaders,
-       })
+       res, err := f.FetchToBuffer(metadataServiceUrl, resource.FetchOptions{})
        return res, err
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/providers/packet/packet.go 
new/ignition-2.1.1/internal/providers/packet/packet.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/providers/packet/packet.go  
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/providers/packet/packet.go      2019-12-13 
23:06:16.000000000 +0100
@@ -55,7 +55,7 @@
 func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
        // Packet's metadata service returns "Not Acceptable" when queried
        // with the default Accept header.
-       headers := resource.ConfigHeaders
+       headers := make(http.Header)
        headers.Set("Accept", "*/*")
        data, err := f.FetchToBuffer(userdataUrl, resource.FetchOptions{
                Headers: headers,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/internal/resource/url.go 
new/ignition-2.1.1/internal/resource/url.go
--- old/ignition-2.0.1+git20191112.a924dd7/internal/resource/url.go     
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/internal/resource/url.go 2019-12-13 23:06:16.000000000 
+0100
@@ -52,7 +52,7 @@
 
        // ConfigHeaders are the HTTP headers that should be used when the 
Ignition
        // config is being fetched
-       ConfigHeaders = http.Header{
+       configHeaders = http.Header{
                "Accept-Encoding": []string{"identity"},
                "Accept":          
[]string{"application/vnd.coreos.ignition+json;version=3.0.0, */*;q=0.1"},
        }
@@ -248,7 +248,21 @@
                }
        }
 
-       dataReader, status, ctxCancel, err := 
f.client.getReaderWithHeader(u.String(), opts.Headers)
+       // TODO use .Clone() when we have a new enough golang
+       // (With Rust, we'd have immutability and wouldn't need to defensively 
clone)
+       headers := make(http.Header)
+       for k, va := range opts.Headers {
+               for _, v := range va {
+                       headers.Add(k, v)
+               }
+       }
+       for k, va := range configHeaders {
+               for _, v := range va {
+                       headers.Add(k, v)
+               }
+       }
+
+       dataReader, status, ctxCancel, err := 
f.client.getReaderWithHeader(u.String(), headers)
        if ctxCancel != nil {
                // whatever context getReaderWithHeader created for the request 
should
                // be cancelled once we're done reading the response
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/tests/blackbox_test.go 
new/ignition-2.1.1/tests/blackbox_test.go
--- old/ignition-2.0.1+git20191112.a924dd7/tests/blackbox_test.go       
2019-11-12 17:46:21.000000000 +0100
+++ new/ignition-2.1.1/tests/blackbox_test.go   2019-12-13 23:06:16.000000000 
+0100
@@ -332,7 +332,7 @@
                        return nil
                }
                if err := umountPartition(rootPartition); err != nil {
-                       return nil
+                       return err
                }
                if filesErr != nil {
                        return nil // error is expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/tests/filesystem.go 
new/ignition-2.1.1/tests/filesystem.go
--- old/ignition-2.0.1+git20191112.a924dd7/tests/filesystem.go  2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/tests/filesystem.go      2019-12-13 23:06:16.000000000 
+0100
@@ -49,11 +49,14 @@
        return out, nil
 }
 
-func prepareRootPartitionForPasswd(ctx context.Context, root *types.Partition) 
error {
-       if err := mountPartition(ctx, root); err != nil {
+func prepareRootPartitionForPasswd(ctx context.Context, root *types.Partition) 
(err error) {
+       err = mountPartition(ctx, root)
+       if err != nil {
                return err
        }
-       defer umountPartition(root)
+       defer func() {
+               err = umountPartition(root)
+       }()
 
        mountPath := root.MountPath
        dirs := []string{
@@ -64,26 +67,25 @@
                filepath.Join(mountPath, "etc"),
        }
        for _, dir := range dirs {
-               err := os.MkdirAll(dir, 0755)
+               err = os.MkdirAll(dir, 0755)
                if err != nil {
-                       return err
+                       return
                }
        }
 
        symlinks := []string{"lib64", "bin", "sbin"}
        for _, symlink := range symlinks {
-               err := os.Symlink(
+               err = os.Symlink(
                        filepath.Join(mountPath, "usr", symlink),
                        filepath.Join(mountPath, symlink))
                if err != nil {
-                       return err
+                       return
                }
        }
 
-       // TODO: use the architecture, not hardcode amd64
        // TODO: needed for user_group_lookup.c
-       _, err := run(ctx, "cp", "/lib64/libnss_files.so.2", 
filepath.Join(mountPath, "usr", "lib64"))
-       return err
+       _, err = run(ctx, "cp", "/lib64/libnss_files.so.2", 
filepath.Join(mountPath, "usr", "lib64"))
+       return
 }
 
 func getRootPartition(partitions []*types.Partition) *types.Partition {
@@ -116,11 +118,8 @@
        if !ok {
                return -1, logs, err
        }
-       status, ok2 := exitErr.Sys().(unix.WaitStatus)
-       if !ok2 {
-               return -1, logs, err
-       }
-       return status.ExitStatus(), logs, nil
+       status := exitErr.ExitCode()
+       return status, logs, nil
 }
 
 func umountPartition(p *types.Partition) error {
@@ -132,24 +131,17 @@
        // specific case. See 
https://github.com/coreos/bootengine/commit/8bf46fe78ec59bcd5148ce9ab8ec5fb805600151
        // for more context.
        for i := 0; i < 3; i++ {
-               status, logs, err := runGetExit("umount", p.MountPath)
-               if status == 0 {
-                       return nil
-               }
-               if err != nil {
-                       return fmt.Errorf("exec'ing `umount %s` failed: %v", 
p.MountPath, err)
-               }
-               if status != 32 {
-                       return fmt.Errorf("`umount %s` failed with exit status 
%d: %s", p.MountPath, status, logs)
+               if err := unix.Unmount(p.MountPath, unix.MNT_FORCE); err != nil 
{
+                       time.Sleep(time.Second)
+                       continue
                }
-               // wait a sec to see if things clear up
-               time.Sleep(time.Second)
-
                if unmounted, _, err := runGetExit("mountpoint", "-q", 
p.MountPath); err != nil {
                        return fmt.Errorf("exec'ing `mountpoint -q %s` failed: 
%v", p.MountPath, err)
                } else if unmounted == 1 {
                        return nil
                }
+               // wait a sec to see if things clear up
+               time.Sleep(time.Second)
        }
        return fmt.Errorf("umount failed after 3 tries (exit status 32) for 
%s", p.MountPath)
 }
@@ -399,26 +391,33 @@
        return r
 }
 
+func createFilesForPartition(ctx context.Context, partition *types.Partition) 
(err error) {
+       err = mountPartition(ctx, partition)
+       if err != nil {
+               return
+       }
+       defer func() {
+               err = umountPartition(partition)
+       }()
+
+       err = createDirectoriesFromSlice(partition.MountPath, 
partition.Directories)
+       if err != nil {
+               return
+       }
+       err = createFilesFromSlice(partition.MountPath, partition.Files)
+       if err != nil {
+               return
+       }
+       err = createLinksFromSlice(partition.MountPath, partition.Links)
+       return
+}
+
 func createFilesForPartitions(ctx context.Context, partitions 
[]*types.Partition) error {
        for _, partition := range partitions {
                if partition.FilesystemType == "swap" || 
partition.FilesystemType == "" || partition.FilesystemType == "blank" {
                        continue
                }
-               if err := mountPartition(ctx, partition); err != nil {
-                       return err
-               }
-               defer umountPartition(partition)
-
-               err := createDirectoriesFromSlice(partition.MountPath, 
partition.Directories)
-               if err != nil {
-                       return err
-               }
-               createFilesFromSlice(partition.MountPath, partition.Files)
-               if err != nil {
-                       return err
-               }
-               createLinksFromSlice(partition.MountPath, partition.Links)
-               if err != nil {
+               if err := createFilesForPartition(ctx, partition); err != nil {
                        return err
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20191112.a924dd7/tests/validator.go 
new/ignition-2.1.1/tests/validator.go
--- old/ignition-2.0.1+git20191112.a924dd7/tests/validator.go   2019-11-12 
17:46:21.000000000 +0100
+++ new/ignition-2.1.1/tests/validator.go       2019-12-13 23:06:16.000000000 
+0100
@@ -183,7 +183,7 @@
        defer func() {
                if err := umountPartition(partition); err != nil {
                        // failing to unmount is not a validation failure
-                       t.Logf("Failed to unmount %s: %v", partition.MountPath, 
err)
+                       t.Fatalf("Failed to unmount %s: %v", 
partition.MountPath, err)
                }
        }()
        for _, file := range partition.Files {


Reply via email to