Hello community,

here is the log from the commit of package ignition for openSUSE:Factory 
checked in at 2019-10-02 14:55:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ignition (Old)
 and      /work/SRC/openSUSE:Factory/.ignition.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ignition"

Wed Oct  2 14:55:55 2019 rev:5 rq:734560 version:2.0.1+git20190925.641ec6a

Changes:
--------
--- /work/SRC/openSUSE:Factory/ignition/ignition.changes        2019-09-11 
10:36:08.007283333 +0200
+++ /work/SRC/openSUSE:Factory/.ignition.new.2352/ignition.changes      
2019-10-02 14:55:58.975272654 +0200
@@ -1,0 +2,24 @@
+Fri Sep 27 11:17:00 UTC 2019 - [email protected]
+
+- Update to version 2.0.1+git20190925.641ec6a:
+  * selinux: use /run/systemd/relabel-extra.d for etc
+  * resource/url: Don't use a tmpfile in FetchToBuffer
+  * resource/url: use only needed ifaces in fetchFrom*
+  * resource/url: make FetchFrom* private
+  * Add a `fetch` stage
+  * build: Add `make install`
+  * tests: fix bb tests for size/start 0
+  * Continue on empty GPT partition label
+  * files/selinux: deglob user/group related paths
+  * stages/files: relabel masking symlinks for systemd
+  * engine: Write `/run/ignition.json` atomically
+  * vendor: Add github.com/google/renameio
+  * stages/filesystems: drop stray debug print
+  * doc/supported-platforms: mention qemu version requirements
+  * Source build file correctly
+  * resource/url: update schema version in Accept header
+  * fix check path mount
+- Drop 0001-Continue-on-empty-GPT-partition-label.patch: Added
+  upstream
+
+-------------------------------------------------------------------

Old:
----
  0001-Continue-on-empty-GPT-partition-label.patch
  ignition-2.0.1+git20190802.d523754.tar.xz

New:
----
  ignition-2.0.1+git20190925.641ec6a.tar.xz

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

Other differences:
------------------
++++++ ignition.spec ++++++
--- /var/tmp/diff_new_pack.oT9W41/_old  2019-10-02 14:55:59.987269999 +0200
+++ /var/tmp/diff_new_pack.oT9W41/_new  2019-10-02 14:55:59.991269989 +0200
@@ -17,14 +17,13 @@
 
 
 Name:           ignition
-Version:        2.0.1+git20190802.d523754
+Version:        2.0.1+git20190925.641ec6a
 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-Continue-on-empty-GPT-partition-label.patch
 Requires:       dracut
 BuildRequires:  dracut
 BuildRequires:  libblkid-devel
@@ -41,7 +40,6 @@
 
 %prep
 %setup -q
-%patch1 -p1
 
 %build
 sed -i -e 's|go build -ldflags|go build -buildmode=pie -ldflags|g' build

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.oT9W41/_old  2019-10-02 14:56:00.039269863 +0200
+++ /var/tmp/diff_new_pack.oT9W41/_new  2019-10-02 14:56:00.039269863 +0200
@@ -1,6 +1,6 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">git://github.com/coreos/ignition.git</param>
-    <param 
name="changesrevision">dedd8ddd5da76a78e630533d87d43b2a4a323e22</param>
+    <param 
name="changesrevision">641ec6a44062f956bf1d46cf10824032a1996590</param>
  </service>
 </servicedata>
\ No newline at end of file

++++++ ignition-2.0.1+git20190802.d523754.tar.xz -> 
ignition-2.0.1+git20190925.641ec6a.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20190802.d523754/Makefile 
new/ignition-2.0.1+git20190925.641ec6a/Makefile
--- old/ignition-2.0.1+git20190802.d523754/Makefile     2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/Makefile     2019-09-25 
21:37:39.000000000 +0200
@@ -1,9 +1,25 @@
 export GO111MODULE=on
 
+# Canonical version of this in 
https://github.com/coreos/coreos-assembler/blob/6eb97016f4dab7d13aa00ae10846f26c1cd1cb02/Makefile#L19
+GOARCH:=$(shell uname -m)
+ifeq ($(GOARCH),x86_64)
+       GOARCH=amd64
+else ifeq ($(GOARCH),aarch64)
+       GOARCH=arm64
+endif
+
 .PHONY: all
 all:
        ./build
 
+# This currently assumes you're using 
https://github.com/coreos/ignition-dracut/
+# If in the future any other initramfs integration appears, feel free to add a 
PR
+# to make this configurable.
+.PHONY: install
+install: all
+       install -m 0755 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition 
bin/$(GOARCH)/ignition
+       install -m 0755 -D -t $(DESTDIR)/usr/bin bin/$(GOARCH)/ignition-validate
+
 .PHONY: vendor
 vendor:
        @go mod vendor
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/build_blackbox_tests 
new/ignition-2.0.1+git20190925.641ec6a/build_blackbox_tests
--- old/ignition-2.0.1+git20190802.d523754/build_blackbox_tests 2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/build_blackbox_tests 2019-09-25 
21:37:39.000000000 +0200
@@ -10,7 +10,7 @@
 GLDFLAGS+="-X 
github.com/coreos/ignition/v2/internal/distro.usermodCmd=usermod-stub "
 GLDFLAGS+="-X 
github.com/coreos/ignition/v2/internal/distro.blackboxTesting=true "
 
-. build
+. ./build
 
 PKG=$(go list ./tests/)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/doc/supported-platforms.md 
new/ignition-2.0.1+git20190925.641ec6a/doc/supported-platforms.md
--- old/ignition-2.0.1+git20190802.d523754/doc/supported-platforms.md   
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/doc/supported-platforms.md   
2019-09-25 21:37:39.000000000 +0200
@@ -8,7 +8,7 @@
 * [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.
-* [QEMU] - Ignition will read its configuration from the 
'opt/com.coreos/config' key on the QEMU Firmware Configuration Device.
+* [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.
 
 Ignition is under active development so expect this list to expand in the 
coming months.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20190802.d523754/go.mod 
new/ignition-2.0.1+git20190925.641ec6a/go.mod
--- old/ignition-2.0.1+git20190802.d523754/go.mod       2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/go.mod       2019-09-25 
21:37:39.000000000 +0200
@@ -8,6 +8,7 @@
        github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142
        github.com/coreos/vcontext v0.0.0-20190529201340-22b159166068
        github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384 // indirect
+       github.com/google/renameio v0.1.0
        github.com/google/uuid v1.1.1
        github.com/kr/pretty v0.1.0 // indirect
        github.com/pin/tftp v2.1.0+incompatible
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20190802.d523754/go.sum 
new/ignition-2.0.1+git20190925.641ec6a/go.sum
--- old/ignition-2.0.1+git20190802.d523754/go.sum       2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/go.sum       2019-09-25 
21:37:39.000000000 +0200
@@ -12,6 +12,8 @@
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384 
h1:xNwo3yd3PZYRDAr/Dz0sBfDWY6El2xPCKJrwJVfMFjY=
 github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384/go.mod 
h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
+github.com/google/renameio v0.1.0 
h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
+github.com/google/renameio v0.1.0/go.mod 
h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
 github.com/google/uuid v1.1.1/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 
h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/engine.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/engine.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/engine.go      
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/engine.go      
2019-09-25 21:37:39.000000000 +0200
@@ -39,6 +39,7 @@
 
        "github.com/coreos/vcontext/report"
        "github.com/coreos/vcontext/validate"
+       "github.com/google/renameio"
 )
 
 const (
@@ -166,7 +167,7 @@
                e.Logger.Crit("failed to marshal cached config: %v", err)
                return
        }
-       if err = ioutil.WriteFile(e.ConfigCache, b, 0640); err != nil {
+       if err = renameio.WriteFile(e.ConfigCache, b, 0640); err != nil {
                e.Logger.Crit("failed to write cached config: %v", err)
                return
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/disks/filesystems.go
 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/disks/filesystems.go
--- 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/disks/filesystems.go
    2019-08-02 19:02:11.000000000 +0200
+++ 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/disks/filesystems.go
    2019-09-25 21:37:39.000000000 +0200
@@ -37,7 +37,6 @@
 // createFilesystems creates the filesystems described in 
config.Storage.Filesystems.
 func (s stage) createFilesystems(config types.Config) error {
        fss := config.Storage.Filesystems
-       s.Logger.Info("fss: %v", fss)
 
        if len(fss) == 0 {
                return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/fetch/fetch.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/fetch/fetch.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/fetch/fetch.go  
1970-01-01 01:00:00.000000000 +0100
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/fetch/fetch.go  
2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,64 @@
+// 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.
+
+// The storage stage is responsible for partitioning disks, creating RAID
+// arrays, formatting partitions, writing files, writing systemd units, and
+// writing network units.
+
+package disks
+
+import (
+       "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
+       "github.com/coreos/ignition/v2/internal/exec/stages"
+       "github.com/coreos/ignition/v2/internal/exec/util"
+       "github.com/coreos/ignition/v2/internal/log"
+       "github.com/coreos/ignition/v2/internal/resource"
+)
+
+const (
+       name = "fetch"
+)
+
+func init() {
+       stages.Register(creator{})
+}
+
+type creator struct{}
+
+func (creator) Create(logger *log.Logger, root string, _ resource.Fetcher) 
stages.Stage {
+       return &stage{
+               Util: util.Util{
+                       DestDir: root,
+                       Logger:  logger,
+               },
+       }
+}
+
+func (creator) Name() string {
+       return name
+}
+
+type stage struct {
+       util.Util
+}
+
+func (stage) Name() string {
+       return name
+}
+
+func (s stage) Run(_ types.Config) error {
+       // Nothing - all we do is fetch and allow anything else in the 
initramfs to run
+       s.Logger.Info("fetch complete")
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/files.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/files.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/files.go  
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/files.go  
2019-09-25 21:37:39.000000000 +0200
@@ -17,7 +17,9 @@
 import (
        "errors"
        "fmt"
+       "io/ioutil"
        "os"
+       "path/filepath"
        "strings"
 
        "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
@@ -30,6 +32,9 @@
 
 const (
        name = "files"
+
+       // see 
https://github.com/systemd/systemd/commit/65e183d7899eb3725d3009196ac4decf1090b580
+       relabelExtraDir = "/run/systemd/relabel-extra.d"
 )
 
 var (
@@ -83,10 +88,18 @@
        }
 
        // add systemd unit to relabel files
-       if err := s.addRelabelUnit(config); err != nil {
+       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)
+       }
+
        return nil
 }
 
@@ -130,8 +143,8 @@
 
 // addRelabelUnit creates and enables a runtime systemd unit to run restorecon
 // if there are files that need to be relabeled.
-func (s *stage) addRelabelUnit(config types.Config) error {
-       if s.toRelabel == nil || len(s.toRelabel) == 0 {
+func (s *stage) addRelabelUnit() error {
+       if len(s.toRelabel) == 0 {
                return nil
        }
        contents := `[Unit]
@@ -179,3 +192,27 @@
        _, 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)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/passwd.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/passwd.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/passwd.go 
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/passwd.go 
2019-09-25 21:37:39.000000000 +0200
@@ -16,10 +16,29 @@
 
 import (
        "fmt"
+       "path/filepath"
 
        "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
 )
 
+func (s *stage) expandGlobList(globs ...string) ([]string, error) {
+       ret := []string{}
+       for _, glob := range globs {
+               matches, err := filepath.Glob(filepath.Join(s.DestDir, glob))
+               if err != nil {
+                       return nil, err
+               }
+               for _, match := range matches {
+                       rel, err := filepath.Rel(s.DestDir, match)
+                       if err != nil {
+                               return nil, err
+                       }
+                       ret = append(ret, filepath.Join("/", rel))
+               }
+       }
+       return ret, nil
+}
+
 // createPasswd creates the users and groups as described in config.Passwd.
 func (s *stage) createPasswd(config types.Config) error {
        if err := s.createGroups(config); err != nil {
@@ -33,13 +52,21 @@
        // to be safe, just blanket mark all passwd-related files rather than
        // trying to make it more granular based on which executables we ran
        if len(config.Passwd.Groups) != 0 || len(config.Passwd.Users) != 0 {
-               s.relabel(
-                       "/etc/passwd*",
+               // Expand the globs now so tools that do not do glob expansion 
can parse them.
+               // Do this before handling files/links/dirs so we don't 
accidently expand paths
+               // for those if the user specifies a path which includes 
globbing characters.
+               deglobbed, err := s.expandGlobList("/etc/passwd*",
                        "/etc/group*",
                        "/etc/shadow*",
                        "/etc/gshadow*",
                        "/etc/subuid*",
-                       "/etc/subgid*",
+                       "/etc/subgid*")
+               if err != nil {
+                       return err
+               }
+
+               s.relabel(deglobbed...)
+               s.relabel(
                        "/etc/.pwd.lock",
                        "/home",
                        "/root",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/units.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/units.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/files/units.go  
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/files/units.go  
2019-09-25 21:37:39.000000000 +0200
@@ -50,12 +50,18 @@
                        enabledOneUnit = true
                }
                if unit.Mask != nil && *unit.Mask {
+                       relabelpath := ""
                        if err := s.Logger.LogOp(
-                               func() error { return s.MaskUnit(unit) },
+                               func() error {
+                                       var err error
+                                       relabelpath, err = s.MaskUnit(unit)
+                                       return err
+                               },
                                "masking unit %q", unit.Name,
                        ); err != nil {
                                return err
                        }
+                       s.relabel(relabelpath)
                }
        }
        // and relabel the preset file itself if we enabled/disabled something
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/mount/mount.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/mount/mount.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/stages/mount/mount.go  
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/stages/mount/mount.go  
2019-09-25 21:37:39.000000000 +0200
@@ -66,7 +66,7 @@
 func (s stage) Run(config types.Config) error {
        fss := []types.Filesystem{}
        for _, fs := range config.Storage.Filesystems {
-               if fs.Path != nil || *fs.Path != "" {
+               if fs.Path != nil && *fs.Path != "" {
                        fss = append(fss, fs)
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/util/blkid.c 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/util/blkid.c
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/util/blkid.c   
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/util/blkid.c   
2019-09-25 21:37:39.000000000 +0200
@@ -200,6 +200,10 @@
 
        // label
        ctmp = blkid_partition_get_name(part);
+       // If the GPT label is empty, then libblkid will return NULL instead of 
an empty string.
+       // There is no NULL value in GPT, so just reset to empty.
+       if (!ctmp)
+               ctmp = "";
        err = checked_copy(info->label, ctmp, PART_INFO_BUF_SIZE);
        if (err)
                return err;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/exec/util/unit.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/exec/util/unit.go
--- old/ignition-2.0.1+git20190802.d523754/internal/exec/util/unit.go   
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/exec/util/unit.go   
2019-09-25 21:37:39.000000000 +0200
@@ -18,6 +18,7 @@
        "fmt"
        "net/url"
        "os"
+       "path/filepath"
 
        "github.com/coreos/ignition/v2/config/v3_1_experimental/types"
        "github.com/coreos/ignition/v2/internal/distro"
@@ -88,19 +89,25 @@
        }, nil
 }
 
-func (ut Util) MaskUnit(unit types.Unit) error {
+// MaskUnit writes a symlink to /dev/null to mask the specified unit and 
returns the path of that unit
+// without the sysroot prefix
+func (ut Util) MaskUnit(unit types.Unit) (string, error) {
        path, err := ut.JoinPath(SystemdUnitsPath(), unit.Name)
        if err != nil {
-               return err
+               return "", err
        }
 
        if err := MkdirForFile(path); err != nil {
-               return err
+               return "", err
        }
        if err := os.RemoveAll(path); err != nil {
-               return err
+               return "", err
        }
-       return os.Symlink("/dev/null", path)
+       if err := os.Symlink("/dev/null", path); err != nil {
+               return "", err
+       }
+       // not the same as the path above, since this lacks the sysroot prefix
+       return filepath.Join("/", SystemdUnitsPath(), unit.Name), nil
 }
 
 func (ut Util) EnableUnit(unit types.Unit) error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ignition-2.0.1+git20190802.d523754/internal/main.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/main.go
--- old/ignition-2.0.1+git20190802.d523754/internal/main.go     2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/main.go     2019-09-25 
21:37:39.000000000 +0200
@@ -23,6 +23,7 @@
        "github.com/coreos/ignition/v2/internal/exec"
        "github.com/coreos/ignition/v2/internal/exec/stages"
        _ "github.com/coreos/ignition/v2/internal/exec/stages/disks"
+       _ "github.com/coreos/ignition/v2/internal/exec/stages/fetch"
        _ "github.com/coreos/ignition/v2/internal/exec/stages/files"
        _ "github.com/coreos/ignition/v2/internal/exec/stages/mount"
        _ "github.com/coreos/ignition/v2/internal/exec/stages/umount"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/internal/resource/url.go 
new/ignition-2.0.1+git20190925.641ec6a/internal/resource/url.go
--- old/ignition-2.0.1+git20190802.d523754/internal/resource/url.go     
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/internal/resource/url.go     
2019-09-25 21:37:39.000000000 +0200
@@ -54,7 +54,7 @@
        // config is being fetched
        ConfigHeaders = http.Header{
                "Accept-Encoding": []string{"identity"},
-               "Accept":          
[]string{"application/vnd.coreos.ignition+json; version=2.2.0, 
application/vnd.coreos.ignition+json; version=1; q=0.5, */*; q=0.1"},
+               "Accept":          
[]string{"application/vnd.coreos.ignition+json;version=3.0.0, */*;q=0.1"},
        }
 )
 
@@ -100,25 +100,50 @@
 // in the contents of the file and delete it. It will return the downloaded
 // contents, or an error if one was encountered.
 func (f *Fetcher) FetchToBuffer(u url.URL, opts FetchOptions) ([]byte, error) {
-       file, err := ioutil.TempFile("", "ignition")
-       if err != nil {
-               return nil, err
-       }
-       defer os.Remove(file.Name())
-       defer file.Close()
-       err = f.Fetch(u, file, opts)
-       if err != nil {
-               return nil, err
+       var err error
+       dest := new(bytes.Buffer)
+       switch u.Scheme {
+       case "http", "https":
+               err = f.fetchFromHTTP(u, dest, opts)
+       case "tftp":
+               err = f.fetchFromTFTP(u, dest, opts)
+       case "data":
+               err = f.fetchFromDataURL(u, dest, opts)
+       case "s3":
+               buf := &s3buf{
+                       WriteAtBuffer: aws.NewWriteAtBuffer([]byte{}),
+               }
+               err = f.fetchFromS3(u, buf, opts)
+               return buf.Bytes(), err
+       case "":
+               return nil, nil
+       default:
+               return nil, ErrSchemeUnsupported
        }
-       _, err = file.Seek(0, os.SEEK_SET)
-       if err != nil {
-               return nil, err
+       return dest.Bytes(), err
+}
+
+// s3buf is a wrapper around the aws.WriteAtBuffer that also allows reading 
and seeking.
+// Read() and Seek() are only safe to call after the download call is made. 
This is only for
+// use with fetchFromS3* functions.
+type s3buf struct {
+       *aws.WriteAtBuffer
+       // only safe to call read/seek after finishing writing. Not safe for 
parallel use
+       reader io.ReadSeeker
+}
+
+func (s *s3buf) Read(p []byte) (int, error) {
+       if s.reader == nil {
+               s.reader = bytes.NewReader(s.Bytes())
        }
-       res, err := ioutil.ReadAll(file)
-       if err != nil {
-               return nil, err
+       return s.reader.Read(p)
+}
+
+func (s *s3buf) Seek(offset int64, whence int) (int64, error) {
+       if s.reader == nil {
+               s.reader = bytes.NewReader(s.Bytes())
        }
-       return res, nil
+       return s.reader.Seek(offset, whence)
 }
 
 // Fetch calls the appropriate FetchFrom* function based on the scheme of the
@@ -134,13 +159,13 @@
 func (f *Fetcher) Fetch(u url.URL, dest *os.File, opts FetchOptions) error {
        switch u.Scheme {
        case "http", "https":
-               return f.FetchFromHTTP(u, dest, opts)
+               return f.fetchFromHTTP(u, dest, opts)
        case "tftp":
-               return f.FetchFromTFTP(u, dest, opts)
+               return f.fetchFromTFTP(u, dest, opts)
        case "data":
-               return f.FetchFromDataURL(u, dest, opts)
+               return f.fetchFromDataURL(u, dest, opts)
        case "s3":
-               return f.FetchFromS3(u, dest, opts)
+               return f.fetchFromS3(u, dest, opts)
        case "":
                return nil
        default:
@@ -150,7 +175,7 @@
 
 // FetchFromTFTP fetches a resource from u via TFTP into dest, returning an
 // error if one is encountered.
-func (f *Fetcher) FetchFromTFTP(u url.URL, dest *os.File, opts FetchOptions) 
error {
+func (f *Fetcher) fetchFromTFTP(u url.URL, dest io.Writer, opts FetchOptions) 
error {
        if !strings.ContainsRune(u.Host, ':') {
                u.Host = u.Host + ":69"
        }
@@ -212,7 +237,7 @@
 
 // FetchFromHTTP fetches a resource from u via HTTP(S) into dest, returning an
 // error if one is encountered.
-func (f *Fetcher) FetchFromHTTP(u url.URL, dest *os.File, opts FetchOptions) 
error {
+func (f *Fetcher) fetchFromHTTP(u url.URL, dest io.Writer, opts FetchOptions) 
error {
        // for the case when "config is not valid"
        // this if necessary if not spawned through kola (e.g. Packet Dashboard)
        if f.client == nil {
@@ -248,7 +273,7 @@
 
 // FetchFromDataURL writes the data stored in the dataurl u into dest, 
returning
 // an error if one is encountered.
-func (f *Fetcher) FetchFromDataURL(u url.URL, dest *os.File, opts 
FetchOptions) error {
+func (f *Fetcher) fetchFromDataURL(u url.URL, dest io.Writer, opts 
FetchOptions) error {
        if opts.Compression != "" {
                return ErrCompressionUnsupported
        }
@@ -260,11 +285,16 @@
        return f.decompressCopyHashAndVerify(dest, bytes.NewBuffer(url.Data), 
opts)
 }
 
+type s3target interface {
+       io.WriterAt
+       io.ReadSeeker
+}
+
 // FetchFromS3 gets data from an S3 bucket as described by u and writes it into
 // dest, returning an error if one is encountered. It will attempt to acquire
 // IAM credentials from the EC2 metadata service, and if this fails will 
attempt
 // to fetch the object with anonymous credentials.
-func (f *Fetcher) FetchFromS3(u url.URL, dest *os.File, opts FetchOptions) 
error {
+func (f *Fetcher) fetchFromS3(u url.URL, dest s3target, opts FetchOptions) 
error {
        if opts.Compression != "" {
                return ErrCompressionUnsupported
        }
@@ -337,7 +367,7 @@
        return nil
 }
 
-func (f *Fetcher) fetchFromS3WithCreds(ctx context.Context, dest *os.File, 
input *s3.GetObjectInput, sess *session.Session) error {
+func (f *Fetcher) fetchFromS3WithCreds(ctx context.Context, dest s3target, 
input *s3.GetObjectInput, sess *session.Session) error {
        httpClient, err := defaultHTTPClient()
        if err != nil {
                return err
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/tests/negative/partitions/zeroes.go 
new/ignition-2.0.1+git20190925.641ec6a/tests/negative/partitions/zeroes.go
--- old/ignition-2.0.1+git20190802.d523754/tests/negative/partitions/zeroes.go  
2019-08-02 19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/tests/negative/partitions/zeroes.go  
2019-09-25 21:37:39.000000000 +0200
@@ -29,8 +29,9 @@
        name := "partition.match.failstofill"
        in := types.GetBaseDisk()
        in[0].Partitions = append(in[0].Partitions, &types.Partition{
-               Number: 10,
-               Length: 65536,
+               Number:   10,
+               Length:   65536,
+               TypeCode: "blank",
        })
        out := in
        config := `{
@@ -42,7 +43,7 @@
                                "partitions": [
                                {
                                        "number": 9,
-                                       "size": 0
+                                       "sizeMiB": 0
                                }
                                ]
                        }
@@ -66,8 +67,9 @@
        //insert a gap before 9
        tmp := in[0].Partitions[9-2-1]
        in[0].Partitions[9-2-1] = &types.Partition{
-               Number: 10,
-               Length: 65536,
+               Number:   10,
+               Length:   65536,
+               TypeCode: "blank",
        }
        in[0].Partitions = append(in[0].Partitions, tmp)
        out := in
@@ -80,7 +82,7 @@
                                "partitions": [
                                {
                                        "number": 9,
-                                       "start": 0
+                                       "startMiB": 0
                                }
                                ]
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/.travis.yml
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/.travis.yml
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/.travis.yml
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/.travis.yml
        2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,16 @@
+sudo: required 
+dist: trusty
+language: go
+go:
+  - "1.11"
+
+install:
+  - go get -t -v -d ./...
+
+script:
+  # Check whether files are syntactically correct.
+  - "gofmt -l $(find . -name '*.go' | tr '\\n' ' ') >/dev/null"
+  # Check whether files were not gofmt'ed.
+  - "gosrc=$(find . -name '*.go' | tr '\\n' ' '); [ $(gofmt -l $gosrc 2>&- | 
wc -l) -eq 0 ] || (echo 'gofmt was not run on these files:'; gofmt -l $gosrc 
2>&-; false)"
+  - go tool vet .
+  - go test -c -race . && sudo ./renameio.test -test.v
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/CONTRIBUTING.md
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/CONTRIBUTING.md
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/CONTRIBUTING.md
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/CONTRIBUTING.md
    2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,28 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement. You (or your employer) retain the copyright to your contribution;
+this simply gives us permission to use and redistribute your contributions as
+part of the project. Head over to <https://cla.developers.google.com/> to see
+your current agreements on file or to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted 
one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
+## Community Guidelines
+
+This project follows [Google's Open Source Community
+Guidelines](https://opensource.google.com/conduct/).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/LICENSE
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/LICENSE
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/LICENSE
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/LICENSE
    2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/README.md
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/README.md
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/README.md
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/README.md
  2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,51 @@
+[![Build 
Status](https://travis-ci.org/google/renameio.svg?branch=master)](https://travis-ci.org/google/renameio)
+[![GoDoc](https://godoc.org/github.com/google/renameio?status.svg)](https://godoc.org/github.com/google/renameio)
+[![Go Report 
Card](https://goreportcard.com/badge/github.com/google/renameio)](https://goreportcard.com/report/github.com/google/renameio)
+
+The `renameio` Go package provides a way to atomically create or replace a 
file or
+symbolic link.
+
+## Atomicity vs durability
+
+`renameio` concerns itself *only* with atomicity, i.e. making sure applications
+never see unexpected file content (a half-written file, or a 0-byte file).
+
+As a practical example, consider https://manpages.debian.org/: if there is a
+power outage while the site is updating, we are okay with losing the manpages
+which were being rendered at the time of the power outage. They will be added 
in
+a later run of the software. We are not okay with having a manpage replaced by 
a
+0-byte file under any circumstances, though.
+
+## Advantages of this package
+
+There are other packages for atomically replacing files, and sometimes ad-hoc
+implementations can be found in programs.
+
+A naive approach to the problem is to create a temporary file followed by a 
call
+to `os.Rename()`. However, there are a number of subtleties which make the
+correct sequence of operations hard to identify:
+
+* The temporary file should be removed when an error occurs, but a remove must
+  not be attempted if the rename succeeded, as a new file might have been
+  created with the same name. This renders a throwaway `defer
+  os.Remove(t.Name())` insufficient; state must be kept.
+
+* The temporary file must be created on the same file system (same mount point)
+  for the rename to work, but the TMPDIR environment variable should still be
+  respected, e.g. to direct temporary files into a separate directory outside 
of
+  the webserver’s document root but on the same file system.
+
+* On POSIX operating systems, the
+  [`fsync`](https://manpages.debian.org/stretch/manpages-dev/fsync.2) system
+  call must be used to ensure that the `os.Rename()` call will not result in a
+  0-length file.
+
+This package attempts to get all of these details right, provides an intuitive,
+yet flexible API and caters to use-cases where high performance is required.
+
+## Disclaimer
+
+This is not an official Google product (experimental or otherwise), it
+is just code that happens to be owned by Google.
+
+This project is not affiliated with the Go project.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/doc.go 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/doc.go
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/doc.go 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/doc.go 
    2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,21 @@
+// Copyright 2018 Google 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 renameio provides a way to atomically create or replace a file or
+// symbolic link.
+//
+// Caveat: this package requires the file system rename(2) implementation to be
+// atomic. Notably, this is not the case when using NFS with multiple clients:
+// https://stackoverflow.com/a/41396801
+package renameio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/go.mod 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/go.mod
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/go.mod 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/go.mod 
    2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1 @@
+module github.com/google/renameio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/tempfile.go
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/tempfile.go
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/tempfile.go
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/tempfile.go
        2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,175 @@
+// Copyright 2018 Google 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 renameio
+
+import (
+       "io/ioutil"
+       "os"
+       "path/filepath"
+)
+
+// TempDir checks whether os.TempDir() can be used as a temporary directory for
+// later atomically replacing files within dest. If no (os.TempDir() resides on
+// a different mount point), dest is returned.
+//
+// Note that the returned value ceases to be valid once either os.TempDir()
+// changes (e.g. on Linux, once the TMPDIR environment variable changes) or the
+// file system is unmounted.
+func TempDir(dest string) string {
+       return tempDir("", filepath.Join(dest, "renameio-TempDir"))
+}
+
+func tempDir(dir, dest string) string {
+       if dir != "" {
+               return dir // caller-specified directory always wins
+       }
+
+       // Chose the destination directory as temporary directory so that we
+       // definitely can rename the file, for which both temporary and 
destination
+       // file need to point to the same mount point.
+       fallback := filepath.Dir(dest)
+
+       // The user might have overridden the os.TempDir() return value by 
setting
+       // the TMPDIR environment variable.
+       tmpdir := os.TempDir()
+
+       testsrc, err := ioutil.TempFile(tmpdir, "."+filepath.Base(dest))
+       if err != nil {
+               return fallback
+       }
+       cleanup := true
+       defer func() {
+               if cleanup {
+                       os.Remove(testsrc.Name())
+               }
+       }()
+       testsrc.Close()
+
+       testdest, err := ioutil.TempFile(filepath.Dir(dest), 
"."+filepath.Base(dest))
+       if err != nil {
+               return fallback
+       }
+       defer os.Remove(testdest.Name())
+       testdest.Close()
+
+       if err := os.Rename(testsrc.Name(), testdest.Name()); err != nil {
+               return fallback
+       }
+       cleanup = false // testsrc no longer exists
+       return tmpdir
+}
+
+// PendingFile is a pending temporary file, waiting to replace the destination
+// path in a call to CloseAtomicallyReplace.
+type PendingFile struct {
+       *os.File
+
+       path   string
+       done   bool
+       closed bool
+}
+
+// Cleanup is a no-op if CloseAtomicallyReplace succeeded, and otherwise closes
+// and removes the temporary file.
+func (t *PendingFile) Cleanup() error {
+       if t.done {
+               return nil
+       }
+       // An error occurred. Close and remove the tempfile. Errors are 
returned for
+       // reporting, there is nothing the caller can recover here.
+       var closeErr error
+       if !t.closed {
+               closeErr = t.Close()
+       }
+       if err := os.Remove(t.Name()); err != nil {
+               return err
+       }
+       return closeErr
+}
+
+// CloseAtomicallyReplace closes the temporary file and atomically replaces
+// the destination file with it, i.e., a concurrent open(2) call will either
+// open the file previously located at the destination path (if any), or the
+// just written file, but the file will always be present.
+func (t *PendingFile) CloseAtomicallyReplace() error {
+       // Even on an ordered file system (e.g. ext4 with data=ordered) or file
+       // systems with write barriers, we cannot skip the fsync(2) call as per
+       // Theodore Ts'o (ext2/3/4 lead developer):
+       //
+       // > data=ordered only guarantees the avoidance of stale data (e.g., 
the previous
+       // > contents of a data block showing up after a crash, where the 
previous data
+       // > could be someone's love letters, medical records, etc.). Without 
the fsync(2)
+       // > a zero-length file is a valid and possible outcome after the 
rename.
+       if err := t.Sync(); err != nil {
+               return err
+       }
+       t.closed = true
+       if err := t.Close(); err != nil {
+               return err
+       }
+       if err := os.Rename(t.Name(), t.path); err != nil {
+               return err
+       }
+       t.done = true
+       return nil
+}
+
+// TempFile wraps ioutil.TempFile for the use case of atomically creating or
+// replacing the destination file at path.
+//
+// If dir is the empty string, TempDir(filepath.Base(path)) is used. If you are
+// going to write a large number of files to the same file system, store the
+// result of TempDir(filepath.Base(path)) and pass it instead of the empty
+// string.
+//
+// The file's permissions will be 0600 by default. You can change these by
+// explicitly calling Chmod on the returned PendingFile.
+func TempFile(dir, path string) (*PendingFile, error) {
+       f, err := ioutil.TempFile(tempDir(dir, path), "."+filepath.Base(path))
+       if err != nil {
+               return nil, err
+       }
+
+       return &PendingFile{File: f, path: path}, nil
+}
+
+// Symlink wraps os.Symlink, replacing an existing symlink with the same name
+// atomically (os.Symlink fails when newname already exists, at least on 
Linux).
+func Symlink(oldname, newname string) error {
+       // Fast path: if newname does not exist yet, we can skip the whole dance
+       // below.
+       if err := os.Symlink(oldname, newname); err == nil || !os.IsExist(err) {
+               return err
+       }
+
+       // We need to use ioutil.TempDir, as we cannot overwrite a 
ioutil.TempFile,
+       // and removing+symlinking creates a TOCTOU race.
+       d, err := ioutil.TempDir(filepath.Dir(newname), 
"."+filepath.Base(newname))
+       if err != nil {
+               return err
+       }
+       defer os.RemoveAll(d)
+
+       symlink := filepath.Join(d, "tmp.symlink")
+       if err := os.Symlink(oldname, symlink); err != nil {
+               return err
+       }
+
+       if err := os.Rename(symlink, newname); err != nil {
+               return err
+       }
+
+       return os.RemoveAll(d)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/writefile.go
 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/writefile.go
--- 
old/ignition-2.0.1+git20190802.d523754/vendor/github.com/google/renameio/writefile.go
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/ignition-2.0.1+git20190925.641ec6a/vendor/github.com/google/renameio/writefile.go
       2019-09-25 21:37:39.000000000 +0200
@@ -0,0 +1,38 @@
+// Copyright 2018 Google 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 renameio
+
+import "os"
+
+// WriteFile mirrors ioutil.WriteFile, replacing an existing file with the same
+// name atomically.
+func WriteFile(filename string, data []byte, perm os.FileMode) error {
+       t, err := TempFile("", filename)
+       if err != nil {
+               return err
+       }
+       defer t.Cleanup()
+
+       // Set permissions before writing data, in case the data is sensitive.
+       if err := t.Chmod(perm); err != nil {
+               return err
+       }
+
+       if _, err := t.Write(data); err != nil {
+               return err
+       }
+
+       return t.CloseAtomicallyReplace()
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ignition-2.0.1+git20190802.d523754/vendor/modules.txt 
new/ignition-2.0.1+git20190925.641ec6a/vendor/modules.txt
--- old/ignition-2.0.1+git20190802.d523754/vendor/modules.txt   2019-08-02 
19:02:11.000000000 +0200
+++ new/ignition-2.0.1+git20190925.641ec6a/vendor/modules.txt   2019-09-25 
21:37:39.000000000 +0200
@@ -52,6 +52,8 @@
 github.com/davecgh/go-spew/spew
 # github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384
 github.com/godbus/dbus
+# github.com/google/renameio v0.1.0
+github.com/google/renameio
 # github.com/google/uuid v1.1.1
 github.com/google/uuid
 # github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af


Reply via email to