diff --git a/internal/providers/qemu/qemu_blockdev.go b/internal/providers/qemu/qemu_blockdev.go new file mode 100644 index 000000000..3a313695f --- /dev/null +++ b/internal/providers/qemu/qemu_blockdev.go @@ -0,0 +1,90 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build s390x ppc64le + +// The QEMU provider on s390x and ppc64le fetches a configuration file from an +// attached block device with id 'virtio-ignition'. + +package qemu + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "time" + + "github.com/coreos/ignition/v2/config/v3_1_experimental/types" + "github.com/coreos/ignition/v2/internal/log" + "github.com/coreos/ignition/v2/internal/providers/util" + "github.com/coreos/ignition/v2/internal/resource" + + "github.com/coreos/vcontext/report" +) + +const ( + ignitionBlockDevicePath = "/dev/disk/by-id/virtio-ignition" + blockDeviceTimeout = 5 * time.Minute + blockDevicePollingInterval = 5 * time.Second +) + +func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { + f.Logger.Warning("Fetching the Ignition config via the Virtio block driver is currently experimental and subject to change.") + + _, err := f.Logger.LogCmd(exec.Command("modprobe", "virtio_blk"), "loading Virtio block driver module") + if err != nil { + return types.Config{}, report.Report{}, err + } + + data, err := fetchConfigFromBlockDevice(f.Logger) + if err != nil { + return types.Config{}, report.Report{}, err + } + + return util.ParseConfig(f.Logger, data) +} + +func fetchConfigFromBlockDevice(logger *log.Logger) ([]byte, error) { + var data []byte + c := make(chan error) + go func() { + var err error + for { + if data, err = ioutil.ReadFile(ignitionBlockDevicePath); err != nil { + if !os.IsNotExist(err) { + break + } + logger.Debug("block device (%q) not found. Waiting...", ignitionBlockDevicePath) + time.Sleep(blockDevicePollingInterval) + } else { + err = nil + break + } + } + c <- err + }() + + select { + case err := <-c: + if err != nil { + return nil, err + } + case <-time.After(blockDeviceTimeout): + return nil, fmt.Errorf("timed out after %v waiting for block device %q to appear", blockDeviceTimeout, ignitionBlockDevicePath) + } + + return bytes.TrimRight(data, "\x00"), nil +} diff --git a/internal/providers/qemu/qemu.go b/internal/providers/qemu/qemu_fwcfg.go similarity index 90% rename from internal/providers/qemu/qemu.go rename to internal/providers/qemu/qemu_fwcfg.go index fb76d5025..0758943e3 100644 --- a/internal/providers/qemu/qemu.go +++ b/internal/providers/qemu/qemu_fwcfg.go @@ -12,8 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The QEMU provider fetches a local configuration from the firmware config -// interface (opt/com.coreos/config). +// +build amd64 arm64 + +// The QEMU provider on amd64 and arm64 fetches a local configuration from the +// firmware config interface (opt/com.coreos/config). package qemu