Skip to content

Commit

Permalink
providers: add initial zVM hypervisor support
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengxiaomei123 committed Sep 29, 2019
1 parent 641ec6a commit bd0fc90
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/supported-platforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Ignition is currently only supported for the following platforms:
* [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 (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.
* [zVM] - Ignition will read its configuration from the reader device directly.The vmur program is necessary,which requires the vmcp and vmur kernel module as prerequisite, and the corresponding z/VM virtual unit record devices (in most cases 000c as reader, 000d as punch) must be set online.

Ignition is under active development so expect this list to expand in the coming months.

Expand Down
5 changes: 5 additions & 0 deletions internal/platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/coreos/ignition/v2/internal/providers/qemu"
"github.com/coreos/ignition/v2/internal/providers/virtualbox"
"github.com/coreos/ignition/v2/internal/providers/vmware"
"github.com/coreos/ignition/v2/internal/providers/zvm"
"github.com/coreos/ignition/v2/internal/registry"
"github.com/coreos/ignition/v2/internal/resource"
)
Expand Down Expand Up @@ -127,6 +128,10 @@ func init() {
name: "metal",
fetch: noop.FetchConfig,
})
configs.Register(Config{
name: "zvm",
fetch: zvm.FetchConfig,
})
}

func Get(name string) (config Config, ok bool) {
Expand Down
102 changes: 102 additions & 0 deletions internal/providers/zvm/zvm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// 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 zVM provider fetches a local configuration from the virtual unit
// record devices.

package zvm

import (
"io/ioutil"
"os/exec"
"strings"

"github.com/coreos/ignition/v2/config/shared/errors"
"github.com/coreos/ignition/v2/config/v3_1_experimental/types"
"github.com/coreos/ignition/v2/internal/log"
"github.com/coreos/ignition/v2/internal/providers/util"
"github.com/coreos/ignition/v2/internal/resource"
"github.com/coreos/vcontext/report"
)

const readerDevice string = "000c"
const configFile string = "config.ign"

func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
// Fetch config files directly from reader device.
_, err := f.Logger.LogCmd(exec.Command("modprobe", "vmur"), "loading zVM control program module")
if err != nil {
f.Logger.Err("couldn't install vmur module: %v", err)
return types.Config{}, report.Report{}, err
}
// Online the reader device.
logger := f.Logger
rc := onlineDevice(logger)
if !rc {
return types.Config{}, report.Report{}, err
}
// Read files from the z/VM reader queue.
var comm string = "vmur li | tail -n +2 | cut -c 1-80 | awk '{print $1,$2,$3,$10,$11}'"
cmd := exec.Command("/bin/sh", "-c", comm)
out, err := cmd.Output()
if err != nil {
f.Logger.Err("Can not get reader device: %v", err)
}
items := strings.Split(string(out), "\n")
for _, records := range items {
record := strings.Split(records, " ")
if len(record) == 1 {
break
}
spoolid := record[1]
filename := record[3]
types := record[4]
var file string
if types == "" {
file = filename
} else {
file = filename + "." + types
}
// Receive the spool file.
if filename == "ignition" {
_, err := f.Logger.LogCmd(exec.Command("vmur", "re", "-f", spoolid, file), "Receive the spool file")
if err == nil {
f.Logger.Info("using config file at %q", file)
_, err := f.Logger.LogCmd(exec.Command("tar", "-xzvf", file), "Extract the spool file")
rawConfig, err := ioutil.ReadFile(configFile)
if err != nil {
f.Logger.Err("couldn't read config %q: %v", filename, err)
break
}
return util.ParseConfig(f.Logger, rawConfig)
}
}
_ = file
}
return types.Config{}, report.Report{}, errors.ErrEmpty
}

func onlineDevice(logger *log.Logger) bool {
_, err := logger.LogCmd(exec.Command("chccwdev", "-e", readerDevice), "Brings a Linux device online")
if err != nil {
_, err = logger.LogCmd(exec.Command("cio_ignore", "-r", readerDevice), "Expose reader device")
_, err = logger.LogCmd(exec.Command("chccwdev", "-e", readerDevice), "Brings a Linux device online")
if err != nil {
logger.Err("Couldn't online reader device")
return (err == nil)
}
}
_, err = logger.LogCmd(exec.Command("udevadm", "settle", "||", "udevsettle"), "Settle udev device")
return (err == nil)
}

0 comments on commit bd0fc90

Please sign in to comment.