Skip to content

kola: add bootc-base tag for kola tests - #4469

Open
yasminvalim wants to merge 5 commits into
coreos:mainfrom
yasminvalim:poc-run-tests
Open

kola: add bootc-base tag for kola tests#4469
yasminvalim wants to merge 5 commits into
coreos:mainfrom
yasminvalim:poc-run-tests

Conversation

@yasminvalim

@yasminvalim yasminvalim commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Adds a bootc-base tag for Kola tests that do not set register.Test.UserData (no test-specific Ignition/Butane).

Summary by CodeRabbit

  • New Features

    • Added a --no-ignition option for QEMU test runs using a supplied disk image.
    • Added support for provisioning SSH access through systemd credentials when Ignition is skipped.
    • Tests marked as bootable base images can now run without test-specific Ignition or Butane configuration.
    • No-Ignition runs connect to QEMU guests as the root user.
  • Bug Fixes

    • Added validation to reject unsupported platforms and missing disk images when --no-ignition is enabled.

@openshift-ci

openshift-ci Bot commented Mar 5, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a --no-ignition flag to kola to allow running tests on pre-baked QCOW2 images, optimizing certain testing scenarios. However, the implementation of the --ssh-user flag introduces a potential SSH configuration injection vulnerability in mantle/platform/cluster.go as the user-supplied SSHUser string is written directly into the ssh-config file without sanitization. It is recommended to sanitize this input to prevent arbitrary SSH option injection. Additionally, consider improving the readability of the machine creation logic in the QEMU platform code.

Comment on lines +154 to +158
if bc.rconf.SSHUser != "" {
if _, err := fmt.Fprintf(sshBuf, " User %s\n", bc.rconf.SSHUser); err != nil {
return err
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The SSHUser command-line flag is written directly into the ssh-config file without sanitization. An attacker who can control the command-line arguments to kola can inject arbitrary SSH configuration options by including newlines in the SSHUser string. This can lead to arbitrary command execution if the ssh-config file is used by the user or another tool (e.g., via ProxyCommand).

Comment thread mantle/platform/machine/qemu/cluster.go Outdated
Comment on lines 71 to 96
qc.mu.Lock()

conf, err := qc.RenderUserData(userdata, map[string]string{})
if err != nil {
noIgnition := qc.RuntimeConf().NoIgnition
var conf *conf.Conf
var confPath string
var err error
if noIgnition {

qc.mu.Unlock()
return nil, err
} else {
conf, err = qc.RenderUserData(userdata, map[string]string{})
if err != nil {
qc.mu.Unlock()
return nil, err
}
qc.mu.Unlock()

if conf.IsIgnition() {
confPath = filepath.Join(dir, "ignition.json")
if err := conf.WriteFile(confPath); err != nil {
return nil, err
}
} else if !conf.IsEmpty() {
return nil, fmt.Errorf("qemu only supports Ignition or empty configs")
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block for handling Ignition is a bit complex and hard to follow due to the locking and branching. It can be simplified by restructuring the if condition and moving the lock to be more tightly scoped around the operation it protects. This will improve readability and maintainability.

noIgnition := qc.RuntimeConf().NoIgnition
	var conf *conf.Conf
	var confPath string
	var err error
	if !noIgnition {
		qc.mu.Lock()
		conf, err = qc.RenderUserData(userdata, map[string]string{})
		qc.mu.Unlock()
		if err != nil {
			return nil, err
		}

		if conf.IsIgnition() {
			confPath = filepath.Join(dir, "ignition.json")
			if err := conf.WriteFile(confPath); err != nil {
				return nil, err
			}
		} else if !conf.IsEmpty() {
			return nil, fmt.Errorf("qemu only supports Ignition or empty configs")
		}
	}

@dustymabe

Copy link
Copy Markdown
Member

TASK:

Running tests that not need ignition against a container image, instead of starting a VM, would drastically reduce the load on the Jenkins infra.

IDEA:

Adapt kola to be able to run tests without relying on ignition

* Assume that we get an ssh key that can log in as root

* Assume that we get a QCOW image with that ssh key injected

* Copy and run tests scripts over SSH in a QEMU VM

* Consider splitting kola for COSA

Do you have any context for all of this? Running nested container images inside kubernetes/openshift (where we run our pipeline today) isn't trivial so I'm not sure if it will save us much.

Also, the description here is contradictory. It says we should be able to run tests against a container, but then you mention a QCOW with an ssh key inject, which is a VM. What's the real goal here?

@yasminvalim

Copy link
Copy Markdown
Contributor Author

TASK:
Running tests that not need ignition against a container image, instead of starting a VM, would drastically reduce the load on the Jenkins infra.
IDEA:
Adapt kola to be able to run tests without relying on ignition

* Assume that we get an ssh key that can log in as root

* Assume that we get a QCOW image with that ssh key injected

* Copy and run tests scripts over SSH in a QEMU VM

* Consider splitting kola for COSA

Do you have any context for all of this? Running nested container images inside kubernetes/openshift (where we run our pipeline today) isn't trivial so I'm not sure if it will save us much.

Also, the description here is contradictory. It says we should be able to run tests against a container, but then you mention a QCOW with an ssh key inject, which is a VM. What's the real goal here?

Hey Dusty, I’ll send over the task and the context I have. To be honest, I’m still figuring it out myself. Since this is a spike, the goal is to investigate and see what’s actually feasible. The DoD in the jira ticket is to create a POC and document the different approaches.

@yasminvalim yasminvalim closed this Apr 7, 2026
@yasminvalim yasminvalim reopened this Apr 7, 2026
@yasminvalim yasminvalim changed the title kola: add --no-ignition flag to run tests without ignition kola: add bootc-base tag for kola tests Apr 8, 2026

@joelcapitao joelcapitao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good overall, though I think we can already add systemd/SMBIOS support in this PR to implement SSH key provisioning.
So, instead of injecting SSH keys via Ignition, QEMU would be started with:

-smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=<base64-encoded-tmpfiles-config>

That way, we'd be able to run the kola bootc-base tagged tests against bootc image.

Comment thread mantle/kola/tests/ostree/sync.go Outdated
@yasminvalim

Copy link
Copy Markdown
Contributor Author

@joelcapitao I added the support for SMBIOS and I guess it's good since I tested manually and worked fine. I need to test with bootc too.

@jlebon jlebon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for working on this!

I think it's OK to try things out by having some of the built-in tests be base bootc-compatible to start. But the real value is in external tests. Once we add enablement for bootc-base for external tests, I would probably even drop all of the internal tags we added to tests here. I don't think it's a good idea to have kola built-in tests be a chokepoint/maintenance burden as we look to scale out kola usage across !CoreOS.

Comment thread mantle/cmd/kola/options.go Outdated
Comment thread mantle/kola/tests/coretest/core.go Outdated
Comment thread mantle/kola/tests/ostree/unlock.go Outdated
Comment thread mantle/kola/tests/rpmostree/deployments.go Outdated
// Use default builder if none provided
builder = qc.ensureBuilderDefaults(builder)

qm, config, err := qc.createMachine(userdata)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createMachine seems to already handle the case where userdata could be nil. Would it be cleaner to instead keep using createMachine, and conditionalize whatever else is needed there on nil userdata?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I got the point here, but I kept createMachine and moved the Ignition vs SMBIOS split there. For bootc runs we key off --no-ignition rather than userdata == nil, since many normal tests pass nil userdata and still expect default Ignition. When the flag isn’t set, nil userdata still goes through RenderUserDataIfNeeded as before. Is that making sense to you? What would be another approach for this?

Comment thread mantle/platform/machine/qemu/cluster.go Outdated
Comment thread mantle/platform/machine/qemu/cluster.go
Comment thread mantle/platform/machine/qemu/cluster.go Outdated
Comment on lines +136 to +140
if qc.flight.opts.Arch != "" {
if err := builder.SetArchitecture(qc.flight.opts.Arch); err != nil {
return nil, err
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like something that should just already be taken care of when builder was constructed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this based in what I saw in qemuiso/cluster.go (line 91 - 101). As far I understood NewQemuBuilder only knows host defaults. Is that right? What would be the best approach in this case?

Comment thread mantle/platform/machine/qemu/cluster.go Outdated
Comment on lines +141 to +143
if qc.flight.opts.Firmware != "" {
builder.Firmware = qc.flight.opts.Firmware
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this too.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds --no-ignition support for QEMU Kola tests. The harness tags bootc-base tests, provisions SSH keys through systemd credentials over virtiofs, skips Ignition rendering, and connects to the VM as root.

Changes

No-Ignition QEMU execution

Layer / File(s) Summary
CLI and test contracts
mantle/cmd/kola/options.go, mantle/platform/platform.go, mantle/platform/machine/qemu/flight.go, mantle/kola/...
Adds and validates --no-ignition, propagates runtime configuration, and tags core bootc-base tests.
SSH credentials and runtime user
mantle/platform/credentials.go, mantle/platform/credentials_test.go, mantle/platform/cluster.go, mantle/kola/harness.go
Generates and tests systemd tmpfiles SSH credentials, selects an explicit SSH user, and sets root for no-Ignition execution.
QEMU no-Ignition provisioning
mantle/platform/machine/qemu/cluster.go, mantle/platform/qemu.go
Skips Ignition rendering, rejects incompatible configuration, mounts credentials through virtiofs, and starts the VM for SSH access.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: joelcapitao, dustymabe

Sequence Diagram(s)

sequenceDiagram
  participant KolaCLI
  participant KolaHarness
  participant QemuCluster
  participant Credentials
  participant QemuGuest
  KolaCLI->>KolaHarness: Enable --no-ignition
  KolaHarness->>QemuCluster: Pass NoIgnition and SSHUser=root
  QemuCluster->>Credentials: Write authorized_keys credentials
  QemuCluster->>QemuGuest: Mount credentials through virtiofs
  QemuGuest-->>QemuCluster: Start for SSH access
  QemuCluster-->>KolaHarness: Connect as root
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects a real part of the PR: adding the bootc-base tag for Kola tests, even though the change also includes no-ignition plumbing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

yasminvalim and others added 4 commits July 15, 2026 13:27
Add kola.BootcBaseTag and tag the coretest basic.* tests that do not
set UserData, so they can be selected with kola run --tag bootc-base.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add helpers to build and write the tmpfiles.extra credential used to
provision SSH keys without Ignition over virtiofs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add MountSystemdCredentialDir() so QEMU shares a host directory with
the guest over virtiofs using the io.systemd.credentials tag.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add --no-ignition to skip Ignition and provision SSH keys via virtiofs
systemd credentials. SSH connects as root. Requires -p qemu and
--qemu-image.

Co-authored-by: Cursor <cursoragent@cursor.com>
…eos-assembler@5ea4caa

Integrate virtiofs systemd credential changes from dustymabe/coreos-assembler
5ea4caa: move credential setup after disk
and network configuration, expand cross-arch documentation, and log virtiofs
tags in debug output.

See https://systemd.io/CREDENTIALS/ for the systemd credentials spec.
See systemd/systemd#29175 for upstream discussion of virtiofs as a credential
transport.

Co-authored-by: Cursor <cursoragent@cursor.com>
@yasminvalim yasminvalim self-assigned this Jul 15, 2026
@yasminvalim
yasminvalim marked this pull request as ready for review July 30, 2026 14:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mantle/platform/machine/qemu/cluster.go`:
- Around line 163-174: Update the QEMU setup flow containing systemdCredDir and
qemuBuilder.MountSystemdCredentialDir so the temporary credential directory is
registered with the QEMU instance/builder cleanup path rather than left as an
independent host temp directory. Ensure setup failures after
WriteSystemdSSHCredentialsDir, including later builder configuration errors,
remove the directory, while preserving cleanup on successful
QemuInstance.Destroy().

In `@mantle/platform/qemu.go`:
- Around line 2032-2036: Update the virtiofs command construction around
createVirtiofsCmd to accept the HostMount.readonly value and add virtiofsd’s
read-only option when it is true. Ensure the virtiofs startup loop propagates
readonly for all mounts, including the systemd credential share, while
preserving writable behavior for mounts marked false.
- Around line 2029-2032: Update the allVirtioFSMounts initialization in the
relevant builder flow to create a zero-length slice with capacity for
builder.hostMounts, then copy the existing mounts into it before appending the
systemd credential mount. Preserve the resulting mount order and contents while
avoiding initialization with a nonzero length before append.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a6dad89a-b556-4535-9c31-9f67f2828864

📥 Commits

Reviewing files that changed from the base of the PR and between cbcb7c7 and 5b5d505.

📒 Files selected for processing (10)
  • mantle/cmd/kola/options.go
  • mantle/kola/harness.go
  • mantle/kola/tests/coretest/core.go
  • mantle/platform/cluster.go
  • mantle/platform/credentials.go
  • mantle/platform/credentials_test.go
  • mantle/platform/machine/qemu/cluster.go
  • mantle/platform/machine/qemu/flight.go
  • mantle/platform/platform.go
  • mantle/platform/qemu.go

Comment on lines +163 to +174
systemdCredDir, err := os.MkdirTemp("", "mantle-systemd-credentials-*")
if err != nil {
return nil, fmt.Errorf("creating systemd credential dir: %w", err)
}
keys, err := qc.Keys()
if err != nil {
return nil, fmt.Errorf("getting SSH keys: %w", err)
}
if err := platform.WriteSystemdSSHCredentialsDir(systemdCredDir, rconf.SSHUser, keys); err != nil {
return nil, err
}
qemuBuilder.MountSystemdCredentialDir(systemdCredDir)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -A80 -B5 'func \(.*\*QemuBuilder\) Close|func \(.*\*QemuInstance\) Destroy|systemdCredentialDir' mantle/platform

Repository: coreos/coreos-assembler

Length of output: 22953


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files 'mantle/platform/*qemu*' 'mantle/platform/machine/qemu/*' | sort

echo
echo "== cluster.go relevant run sections =="
wc -l mantle/platform/machine/qemu/cluster.go mantle/platform/qemu.go
sed -n '130,195p;210,260p' mantle/platform/machine/qemu/cluster.go

echo
echo "== qemu.go relevant lifecycle sections =="
sed -n '490,575p;1980,2215p' mantle/platform/qemu.go

echo
echo "== usages of qc.Keys and platform.WriteSystemdSSHCredentialsDir =="
rg -n -C4 'WriteSystemdSSHCredentialsDir|systemdCredDir|MountSystemdCredentialDir' mantle/platform

Repository: coreos/coreos-assembler

Length of output: 18886


Release the systemd credential directory with the QEMU instance.

The systemdCredDir created by MkdirTemp("", ...) is passed directly to the host machine and is not transferred into builder.tempdir/inst.tempdir, so QemuInstance.Destroy() does not remove it. Also, failures after WriteSystemdSSHCredentialsDir() can return without removing the partial directory. Move the path into the QEMU cleanup path and remove it on later setup failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mantle/platform/machine/qemu/cluster.go` around lines 163 - 174, Update the
QEMU setup flow containing systemdCredDir and
qemuBuilder.MountSystemdCredentialDir so the temporary credential directory is
registered with the QEMU instance/builder cleanup path rather than left as an
independent host temp directory. Ensure setup failures after
WriteSystemdSSHCredentialsDir, including later builder configuration errors,
remove the directory, while preserving cleanup on successful
QemuInstance.Destroy().

Comment thread mantle/platform/qemu.go
Comment on lines +2029 to +2032
allVirtioFSMounts := make([]HostMount, len(builder.hostMounts))
copy(allVirtioFSMounts, builder.hostMounts)
if builder.systemdCredentialDir != "" {
allVirtioFSMounts = append(allVirtioFSMounts, HostMount{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the makezero lint failure.

golangci-lint reports this initialized-length slice is subsequently appended to.

Proposed fix
-	allVirtioFSMounts := make([]HostMount, len(builder.hostMounts))
-	copy(allVirtioFSMounts, builder.hostMounts)
+	allVirtioFSMounts := make([]HostMount, 0, len(builder.hostMounts)+1)
+	allVirtioFSMounts = append(allVirtioFSMounts, builder.hostMounts...)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
allVirtioFSMounts := make([]HostMount, len(builder.hostMounts))
copy(allVirtioFSMounts, builder.hostMounts)
if builder.systemdCredentialDir != "" {
allVirtioFSMounts = append(allVirtioFSMounts, HostMount{
allVirtioFSMounts := make([]HostMount, 0, len(builder.hostMounts)+1)
allVirtioFSMounts = append(allVirtioFSMounts, builder.hostMounts...)
if builder.systemdCredentialDir != "" {
allVirtioFSMounts = append(allVirtioFSMounts, HostMount{
🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 2032-2032: append to slice allVirtioFSMounts with non-zero initialized length

(makezero)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mantle/platform/qemu.go` around lines 2029 - 2032, Update the
allVirtioFSMounts initialization in the relevant builder flow to create a
zero-length slice with capacity for builder.hostMounts, then copy the existing
mounts into it before appending the systemd credential mount. Preserve the
resulting mount order and contents while avoiding initialization with a nonzero
length before append.

Source: Linters/SAST tools

Comment thread mantle/platform/qemu.go
Comment on lines +2032 to +2036
allVirtioFSMounts = append(allVirtioFSMounts, HostMount{
src: builder.systemdCredentialDir,
dest: SystemdCredentialVirtiofsTag,
readonly: true,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -A35 -B5 'func createVirtiofsCmd|HostMount|readonly' mantle/platform/qemu.go

Repository: coreos/coreos-assembler

Length of output: 15482


🌐 Web query:

virtiofsd --readonly option read-only mount documentation

💡 Result:

The --readonly option in virtiofsd is used to prevent write access to the shared directory from the guest [1][2]. When this option is enabled, the guest is unable to modify the contents of the shared file system [1][2]. It is important to note that --readonly does not make the underlying host directory an actual read-only mount [1][2]. Consequently, certain metadata, such as file access times (atime), may still be updated on the host when accessed from the guest [1][2]. For scenarios requiring a true read-only configuration, documentation recommends exporting a read-only mount point from the host [3][1][2]. This can be achieved by creating a separate mount point with read-only permissions and then pointing virtiofsd to that directory [3][1][2]. Example usage for read-only sharing: Using the --readonly flag: virtiofsd --shared-dir /path/to/share --readonly... Using a read-only bind mount: mkdir /path/to/ro-share mount -o bind,ro /path/to/share /path/to/ro-share virtiofsd --shared-dir /path/to/ro-share...

Citations:


Enforce readonly for virtiofs mounts before starting virtiofsd.

HostMount.readonly is populated for the systemd credential share, but the loop ignores it and createVirtiofsCmd() never adds virtiofsd’s --readonly flag. Add an option/argument for read-only virtiofs mounts and use it for mounts like the credential dir so the host temp directory cannot be modified by the guest.

🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 2032-2032: append to slice allVirtioFSMounts with non-zero initialized length

(makezero)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mantle/platform/qemu.go` around lines 2032 - 2036, Update the virtiofs
command construction around createVirtiofsCmd to accept the HostMount.readonly
value and add virtiofsd’s read-only option when it is true. Ensure the virtiofs
startup loop propagates readonly for all mounts, including the systemd
credential share, while preserving writable behavior for mounts marked false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants