Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/kola/external-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ Here's an example `kola.json`:
"additionalNics": 2,
"appendKernelArgs": "enforcing=0"
"appendFirstbootKernelArgs": "ip=bond0:dhcp bond=bond0:ens5,ens6:mode=active-backup,miimon=100"
"bindMountHostRO": ["/,/var/cosaroot"],
"timeoutMin": 8,
"exclusive": true,
"conflicts": ["ext.config.some-test", "podman.some-other-test"],
Expand Down
2 changes: 1 addition & 1 deletion mantle/cmd/kola/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func init() {
bv(&kola.QEMUOptions.Disk512e, "qemu-512e", false, "Force 512e layout for main disk")
bv(&kola.QEMUOptions.Nvme, "qemu-nvme", false, "Use NVMe for main disk")
bv(&kola.QEMUOptions.Swtpm, "qemu-swtpm", true, "Create temporary software TPM")
ssv(&kola.QEMUOptions.BindRO, "qemu-bind-ro", nil, "Inject a host directory; this does not automatically mount in the guest")
ssv(&kola.QEMUOptions.BindRO, "qemu-bind-ro", nil, "Mount $hostpath,$guestpath readonly; for example --qemu-bind-ro=/path/on/host,/var/mnt/guest)")

sv(&kola.QEMUIsoOptions.IsoPath, "qemu-iso", "", "path to CoreOS ISO image")
bv(&kola.QEMUIsoOptions.AsDisk, "qemu-iso-as-disk", false, "attach ISO image as regular disk")
Expand Down
12 changes: 2 additions & 10 deletions mantle/cmd/kola/qemuexec.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@ func renderFragments(fragments []string, c *conf.Conf) error {
return nil
}

func parseBindOpt(s string) (string, string, error) {
parts := strings.SplitN(s, ",", 2)
if len(parts) == 1 {
return "", "", fmt.Errorf("malformed bind option, required: SRC,DEST")
}
return parts[0], parts[1], nil
}

// buildDiskFromOptions generates a disk image template using the process-global
// defaults that were parsed from command line arguments.
func buildDiskFromOptions() *platform.Disk {
Expand Down Expand Up @@ -304,7 +296,7 @@ func runQemuExec(cmd *cobra.Command, args []string) error {
}

for _, b := range bindro {
src, dest, err := parseBindOpt(b)
src, dest, err := platform.ParseBindOpt(b)
if err != nil {
return err
}
Expand All @@ -313,7 +305,7 @@ func runQemuExec(cmd *cobra.Command, args []string) error {
config.MountHost(dest, true)
}
for _, b := range bindrw {
src, dest, err := parseBindOpt(b)
src, dest, err := platform.ParseBindOpt(b)
if err != nil {
return err
}
Expand Down
7 changes: 5 additions & 2 deletions mantle/kola/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"math/rand"
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -1015,6 +1016,7 @@ type externalTestMeta struct {
NoInstanceCreds bool `json:"noInstanceCreds" yaml:"noInstanceCreds"`
InstanceType string `json:"instanceType" yaml:"instanceType"`
Description string `json:"description" yaml:"description"`
BindMountHostRO []string `json:"bindMountHostRO,omitempty" yaml:"bindMountHostRO,omitempty"`
}

// metadataFromTestBinary extracts JSON-in-comment like:
Expand Down Expand Up @@ -1239,6 +1241,7 @@ ExecStart=%s
Tags: []string{"external"},

MachineOptions: platform.MachineOptions{
BindMountHostRO: targetMeta.BindMountHostRO,
AdditionalDisks: targetMeta.AdditionalDisks,
PrimaryDisk: targetMeta.PrimaryDisk,
MinMemory: targetMeta.MinMemory,
Expand Down Expand Up @@ -1622,8 +1625,8 @@ func makeNonExclusiveTest(bucket int, tests []*register.Test, flight platform.Fl
if test.HasFlag(register.AllowConfigWarnings) {
plog.Fatalf("Non-exclusive test %v cannot have AllowConfigWarnings flag", test.Name)
}
if test.MachineOptions.AppendKernelArgs != "" {
plog.Fatalf("Non-exclusive test %v cannot have AppendKernelArgs", test.Name)
if !reflect.DeepEqual(test.MachineOptions, platform.MachineOptions{}) {
plog.Fatalf("Non-exclusive test %v cannot have MachineOptions set", test.Name)
}
if !internetAccess && testRequiresInternet(test) {
tags = append(tags, NeedsInternetTag)
Expand Down
26 changes: 18 additions & 8 deletions mantle/platform/machine/qemu/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"sync/atomic"
"time"

Expand Down Expand Up @@ -86,6 +85,24 @@ func (qc *Cluster) NewMachineWithOptions(userdata *conf.UserData, options platfo
}
}

// If requested, bind mount Host (COSA) directories into the machine for use.
// These could either come in as MachineOptions OR via the flight options
// (CLI --qemu-bind-ro option).
//
// One example where this is useful is using the host environment (COSA)
// as a read-only rootfs for quickly starting a container. This use was originally
// pioneered in testiso in [1].
// [1] https://github.com/coreos/coreos-assembler/commit/8dbfe3ea8b8f571e732e8cc0ab307e983a0be1f3
for _, mountpair := range append(qc.flight.opts.BindRO, options.BindMountHostRO...) {
src, dest, err := platform.ParseBindOpt(mountpair)
if err != nil {
return nil, err
}
readonly := true
builder.MountHost(src, dest, readonly)
config.MountHost(dest, readonly)
}

builder.SetConfig(config)
defer builder.Close()
builder.UUID = qm.id
Expand All @@ -101,13 +118,6 @@ func (qc *Cluster) NewMachineWithOptions(userdata *conf.UserData, options platfo
builder.Hostname = fmt.Sprintf("qemu%d", qc.BaseCluster.AllocateMachineSerial())
builder.ConsoleFile = qm.consolePath

// This one doesn't support configuring the path because we can't
// reliably change the Ignition config here...
for _, path := range qc.flight.opts.BindRO {
destpathrel := strings.TrimLeft(path, "/")
builder.MountHost(path, "/kola/host/"+destpathrel, true)
}

if qc.flight.opts.Memory != "" {
memory, err := strconv.ParseInt(qc.flight.opts.Memory, 10, 32)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions mantle/platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ type MachineOptions struct {
OverrideBackingFile string
Nvme bool
Cex bool
BindMountHostRO []string
}

// EnsureNoQEMUOnlyOptions returns an error if any QEMU-only options
Expand Down Expand Up @@ -221,6 +222,9 @@ func (m *MachineOptions) EnsureNoQEMUOnlyOptions(platformName string) error {
if m.Cex {
return fmt.Errorf("platform %s does not support Cex", platformName)
}
if len(m.BindMountHostRO) > 0 {
return fmt.Errorf("platform %s does not support bind mounting host paths", platformName)
}
return nil
}

Expand Down
9 changes: 9 additions & 0 deletions mantle/platform/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ func ParseDisk(spec string, allowNoSize bool) (*Disk, error) {
}, nil
}

// Parse the src/dest for BindRO and BindRW options
func ParseBindOpt(spec string) (string, string, error) {
parts := strings.SplitN(spec, ",", 2)
if len(parts) == 1 {
return "", "", fmt.Errorf("malformed bind option, required: SRC,DEST")
}
return parts[0], parts[1], nil
}

// bootIso is an internal struct used by AddIso() and setupIso()
type bootIso struct {
path string
Expand Down
4 changes: 4 additions & 0 deletions src/deps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,7 @@ vim-enhanced

# For reading build-args.conf (environment file)
python3-dotenv

# For testing numad
# https://github.com/coreos/fedora-coreos-config/pull/4051
stress-ng