Skip to content

Add LVMS analyze skill for storage troubleshooting#194

Merged
openshift-merge-bot[bot] merged 4 commits into
openshift-eng:mainfrom
suleymanakbas91:add-lvms-analyze-skill
Jun 16, 2026
Merged

Add LVMS analyze skill for storage troubleshooting#194
openshift-merge-bot[bot] merged 4 commits into
openshift-eng:mainfrom
suleymanakbas91:add-lvms-analyze-skill

Conversation

@suleymanakbas91

@suleymanakbas91 suleymanakbas91 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Moves the LVMS analyze skill from openshift-eng/ai-helpers into the existing LVMS plugin
  • The skill diagnoses LVMS storage issues on both live clusters (via oc commands) and offline must-gather data (via Python analysis script)
  • Consolidates the original command + skill into a single concise SKILL.md (~130 lines vs ~1300 lines combined)
  • Improves the Python script to handle individual PV/SC files from must-gather alongside list-format YAML
  • Bumps plugin version to 1.1.0

Companion PR

The removal of the LVMS plugin from openshift-eng/ai-helpers will follow in a separate PR to that repo.

Test plan

  • Verify /lvms:analyze --help shows correct usage
  • Test must-gather analysis with the Python script against an LVMS must-gather
  • Test live cluster analysis on a cluster with LVMS installed
  • Verify skill linter passes (make lint-all-skills)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added the /lvms:analyze skill for troubleshooting LVMS on OpenShift.
    • Supports live diagnostics and offline must-gather analysis with component-scoped checks, health indicators, and recommendations.
  • Documentation
    • Updated the LVMS plugin README with /lvms:analyze usage, examples, and requirements.
    • Added a dedicated skill reference detailing inputs, modes, and structured report output.
  • Chores
    • Bumped the LVMS plugin version to 1.1.0 and expanded public plugin metadata to include release/QE workflows and troubleshooting.

Move the LVMS analyze skill from openshift-eng/ai-helpers into the
existing LVMS plugin. The skill diagnoses LVMS storage issues on live
clusters (via oc commands) and offline must-gather data (via Python
analysis script).

Compared to the original, this version:
- Consolidates the command + skill into a single SKILL.md (~130 lines
  vs ~1300 lines combined)
- Improves the Python script to handle individual PV/SC files from
  must-gather alongside list-format YAML
- Adds early PyYAML import check with a clear error message
- Simplifies deduplication and resource extraction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: suleymanakbas91

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The LVMS plugin is updated to version 1.1.0 with the addition of a new lvms:analyze skill. The skill comprises a behavior specification defining two execution modes (offline must-gather Python script and live cluster oc commands) and a 591-line Python analyzer that loads YAML resources, runs component-scoped diagnostic checks, and emits a structured report with health indicators and recommendations.

Changes

LVMS v1.1.0: Analyze Skill Addition

Layer / File(s) Summary
Plugin manifest version bumps
.claude-plugin/marketplace.json, plugins/lvms/.claude-plugin/plugin.json
Version incremented from 1.0.0 to 1.1.0 and description expanded to include troubleshooting in both manifests.
lvms:analyze skill specification and execution modes
plugins/lvms/skills/analyze/SKILL.md
New skill document defining metadata, synopsis and examples for both offline must-gather Python script and live cluster oc commands execution modes, component-scoped argument handling, resource collection command sets, health checks, and report output format with health indicators and recommendations.
Python analyzer: utilities and initialization
plugins/lvms/skills/analyze/scripts/analyze_lvms.py
ANSI color constants and output helper functions; YAML loading utilities that normalize Kubernetes YAML structures into item lists; LVMSAnalyzer.__init__ and validate() detecting namespace exports with fallback guidance.
Python analyzer: resource and log loading
plugins/lvms/skills/analyze/scripts/analyze_lvms.py
load_resources() traverses must-gather directory to populate LVMCluster CRs, Pod manifests, core events, LVMS-filtered PVCs/PVs by storage class and CSI driver, TopoLVM storage classes, and deployment/daemonset specs; load_pod_logs() and _parse_log() extract JSON log entries filtered by error/warning severity, deduplicated by message with earliest timestamp preserved.
Python analyzer: component-scoped diagnostic methods
plugins/lvms/skills/analyze/scripts/analyze_lvms.py
Six analysis methods (analyze_lvmcluster, analyze_volume_groups, analyze_pvcs, analyze_operator_health, analyze_storage_classes, analyze_pod_logs) inspect loaded resources, evaluate health conditions and node readiness states, detect non-Bound PVCs and problematic Pod phases, and accumulate critical/warning issues with event correlations and container termination details.
Python analyzer: orchestration, summary, and CLI
plugins/lvms/skills/analyze/scripts/analyze_lvms.py
summary() prints issue counts and conditionally selected recommendations based on substring matching against accumulated issue messages; run(component='all') validates input, loads resources and logs, dispatches component-scoped analysis, and returns exit code based on validation and critical issue presence; main() implements argparse CLI with required must_gather_path and constrained --component choices.
README and plugin documentation updates
plugins/lvms/README.md
Adds /lvms:analyze to Skills list, includes Troubleshooting subsection with example commands for analyzing live clusters and must-gather directories with optional component focusing, and extends Requirements with Python 3 with PyYAML dependency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • openshift-eng/edge-tooling#72: Updates LVMS plugin marketplace/manifest metadata (version and description fields) in the same files, though only this PR adds the complete lvms:analyze skill implementation and documentation.

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The analyze_lvms.py script prints unfiltered Kubernetes object data containing potential secrets: StorageClass parameters (line 481-484), pod log error/message fields (line 501-514), Kubernetes con... Filter or redact sensitive fields: (1) sanitize StorageClass parameters, (2) redact error traces, (3) filter condition messages, (4) sanitize event messages to prevent logging passwords, tokens, API keys, hostnames, or credentials.
Docstring Coverage ⚠️ Warning Docstring coverage is 4.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ai-Attribution ⚠️ Warning Commit uses Co-Authored-By for AI tool (Claude) and lacks Red Hat Assisted-by/Generated-by trailers required by the check. Replace Co-Authored-By with Assisted-by or Generated-by trailer per Red Hat attribution standards; add Red Hat authorship trailer.
✅ Passed checks (8 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a new LVMS analyze skill for storage troubleshooting.
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.
No-Weak-Crypto ✅ Passed No weak cryptography patterns detected. The PR adds diagnostic tooling that uses only standard Python libraries (yaml, json, argparse) with no cryptographic algorithms, implementations, or secret c...
Container-Privileges ✅ Passed No container privilege escalation flags found. PR adds documentation and analysis scripts without defining any Kubernetes manifests with privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN capabil...
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets, API keys, tokens, passwords, private keys, or suspicious base64 strings found in any modified files.
No-Injection-Vectors ✅ Passed The code avoids all injection vector vulnerabilities: uses yaml.safe_load_all (not yaml.load), JSON parsing with json.loads exception handling, no eval/exec/os.system/pickle.loads, no shell=True, s...
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (2)
plugins/lvms/skills/analyze/SKILL.md (1)

163-168: ⚡ Quick win

Inline common failure patterns with relevant workflow steps.

Per retrieved learning (PR 192: microshift-ci), failure policies and edge-case rules should be "co-located inline with the specific step that needs them" rather than in a separate reference section. The LLM reads linearly and may not reliably re-consult separate sections mid-execution.

Suggestion: Move each root-cause pattern (device filesystem conflict, insufficient capacity, duplicate VG names, node-specific failure) inline with the analysis step where it would be detected. For example, the "device filesystem conflict" pattern should live with Step 4's VG analysis block (lines 102–109), and the "insufficient capacity" pattern should follow the thin pool checks.

🤖 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 `@plugins/lvms/skills/analyze/SKILL.md` around lines 163 - 168, Move the common
root cause patterns from the separate "Common Root Cause Patterns" section
(currently at lines 163-168) inline with the relevant workflow steps earlier in
the document. Specifically: embed the "Device filesystem conflict" pattern
directly within Step 4's VG analysis block (lines 102-109), place the
"Insufficient capacity" pattern inline with the thin pool capacity checks, and
co-locate each remaining pattern (duplicate VG names, node-specific failure)
with the specific analysis step where it would be detected. This ensures the LLM
encounters failure patterns and edge-case rules in the same context where it
performs the corresponding diagnostic check, rather than relying on separate
reference sections that may not be consulted during linear execution.

Source: Learnings

plugins/lvms/skills/analyze/scripts/analyze_lvms.py (1)

56-64: ⚡ Quick win

Missing explicit file encoding in file operations. Both load_yaml() and _parse_log() open files without specifying encoding, which defaults to the system locale and can cause issues with UTF-8 content on some platforms.

  • plugins/lvms/skills/analyze/scripts/analyze_lvms.py#L56-L64: Add encoding='utf-8' to open(path) in load_yaml().
  • plugins/lvms/skills/analyze/scripts/analyze_lvms.py#L213-L240: Add encoding='utf-8' to open(path) in _parse_log().
🤖 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 `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py` around lines 56 - 64,
File operations are missing explicit UTF-8 encoding specifications which can
cause platform-specific issues. In
plugins/lvms/skills/analyze/scripts/analyze_lvms.py, locate the `load_yaml()`
function (lines 56-64) and add `encoding='utf-8'` parameter to the `open(path)`
call. Then locate the `_parse_log()` function (lines 213-240) and add the same
`encoding='utf-8'` parameter to its `open(path)` call. This ensures consistent
UTF-8 file handling across all platforms.
🤖 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 `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py`:
- Around line 152-174: The code for loading PersistentVolumes and StorageClasses
processes both individual files and list files, which may contain the same
resources causing duplicates in self.pvs and self.storage_classes. To fix this,
deduplicate by resource UID: before appending a PV in the PV loading block
(where you check for topolvm.io driver) or a StorageClass in the StorageClass
loading block (where you check for topolvm.io provisioner), first check if a
resource with the same UID has already been added; use a set to track seen UIDs
across both the individual file and list file loops to prevent duplicates from
being appended.
- Around line 332-339: The if reason block (lines 332-339) that appends to
self.issues['critical'] is currently executing for all nodes regardless of
status, causing Ready nodes with informational reasons to be incorrectly flagged
as critical issues. Move the entire if reason block (including the print
statements and the critical append operation) inside the conditional that
handles non-Ready node statuses, so that only nodes without a Ready status will
have their reasons logged and flagged as critical issues.

---

Nitpick comments:
In `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py`:
- Around line 56-64: File operations are missing explicit UTF-8 encoding
specifications which can cause platform-specific issues. In
plugins/lvms/skills/analyze/scripts/analyze_lvms.py, locate the `load_yaml()`
function (lines 56-64) and add `encoding='utf-8'` parameter to the `open(path)`
call. Then locate the `_parse_log()` function (lines 213-240) and add the same
`encoding='utf-8'` parameter to its `open(path)` call. This ensures consistent
UTF-8 file handling across all platforms.

In `@plugins/lvms/skills/analyze/SKILL.md`:
- Around line 163-168: Move the common root cause patterns from the separate
"Common Root Cause Patterns" section (currently at lines 163-168) inline with
the relevant workflow steps earlier in the document. Specifically: embed the
"Device filesystem conflict" pattern directly within Step 4's VG analysis block
(lines 102-109), place the "Insufficient capacity" pattern inline with the thin
pool capacity checks, and co-locate each remaining pattern (duplicate VG names,
node-specific failure) with the specific analysis step where it would be
detected. This ensures the LLM encounters failure patterns and edge-case rules
in the same context where it performs the corresponding diagnostic check, rather
than relying on separate reference sections that may not be consulted during
linear execution.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 5a67ca2a-3f8a-446e-8d1f-9c48aad30782

📥 Commits

Reviewing files that changed from the base of the PR and between ae84e9f and 060072c.

📒 Files selected for processing (5)
  • .claude-plugin/marketplace.json
  • plugins/lvms/.claude-plugin/plugin.json
  • plugins/lvms/README.md
  • plugins/lvms/skills/analyze/SKILL.md
  • plugins/lvms/skills/analyze/scripts/analyze_lvms.py

Comment thread plugins/lvms/skills/analyze/scripts/analyze_lvms.py Outdated
Comment thread plugins/lvms/skills/analyze/scripts/analyze_lvms.py Outdated
- Fix PV/SC duplicate loading by deduplicating by UID/name
- Fix VG reason wrongly flagged as critical for Ready nodes
- Add explicit encoding='utf-8' to file open calls
- Move root cause patterns inline with relevant analysis steps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jun 15, 2026
General OCP must-gathers don't include LVMS CRDs (LVMCluster), only
pods/deployments/daemonsets. Downgrade missing LVMCluster from CRITICAL
to WARNING when other LVMS components are present, and suggest using the
LVMS-specific must-gather image for full CRD data. Also add a fallback
search for individual lvmclusters/*.yaml files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai coderabbitai Bot removed the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jun 15, 2026

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugins/lvms/skills/analyze/scripts/analyze_lvms.py (2)

345-359: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Progressing nodes with reasons are added to both warning and critical lists.

When a node has status 'Progressing' with a reason, line 347 adds it to warnings, but line 359 also adds it to critical issues. This double-counts the issue.

Proposed fix - skip critical append for Progressing status
                     if reason and st != 'Ready':
                         print(f"\n  {BOLD}Reason:{END}")
                         lines = reason.split('\n')
                         for line in lines[:5]:
                             print(f"  {line}")
                         if len(lines) > 5:
                             print(f"  ... (truncated, {len(lines) - 5} more lines)")
-                        self.issues['critical'].append(f"VG {vg_name} on {node}: {reason[:200]}")
+                        if st != 'Progressing':
+                            self.issues['critical'].append(f"VG {vg_name} on {node}: {reason[:200]}")
🤖 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 `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py` around lines 345 - 359,
When a VG node has status 'Progressing' with a reason, it is being added to both
the 'warning' list (at line 347) and the 'critical' list (at line 359), causing
double-counting of the same issue. Modify the condition that controls whether to
append to self.issues['critical'] on line 359 to exclude 'Progressing' status.
The condition currently checks `if reason and st != 'Ready':` but should also
exclude 'Progressing' by adding an additional check `and st != 'Progressing'` so
that 'Progressing' status items are only added to warnings, not critical issues.

499-518: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Error-level log entries without an error field are not added to issue tracking.

The issue tracking logic (lines 514-517) is nested inside if e['error']:, so log entries at error level that lack an error field are printed but not accumulated in self.issues. This may cause the summary to undercount errors.

Proposed fix - track issues regardless of error field
             for e in sorted(entries, key=lambda x: x['ts']):
                 (err if e['level'] == 'error' else warn)(f"{e['ts']}: {e['msg']}")
                 if e['controller']:
                     print(f"  Controller: {e['controller']}")
                 if e['error']:
                     lines = e['error'].split('\n')
                     if len(lines) > 1:
                         print(f"  {BOLD}Error Details:{END}")
                         for line in lines[:10]:
                             if line.strip():
                                 print(f"    {line}")
                         if len(lines) > 10:
                             print(f"    ... ({len(lines) - 10} more lines)")
                     else:
                         print(f"  Error: {e['error']}")
-                    if e['level'] == 'error':
-                        self.issues['critical'].append(f"Pod {pod}: {e['msg']}")
-                    else:
-                        self.issues['warning'].append(f"Pod {pod}: {e['msg']}")
+                if e['level'] == 'error':
+                    self.issues['critical'].append(f"Pod {pod}: {e['msg']}")
+                else:
+                    self.issues['warning'].append(f"Pod {pod}: {e['msg']}")
                 print()
🤖 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 `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py` around lines 499 - 518,
The issue tracking logic that appends to self.issues['critical'] and
self.issues['warning'] is currently nested inside the if e['error']: condition,
which means error-level entries without an error field are not tracked in the
issues summary. Move the if/else block that checks e['level'] == 'error' and
appends to self.issues outside of the if e['error']: block so that all error and
warning level entries are tracked regardless of whether the error field is
present. The error field display logic can remain nested, but the issue tracking
must execute for every entry that has an error or warning level.
🧹 Nitpick comments (1)
plugins/lvms/skills/analyze/scripts/analyze_lvms.py (1)

217-223: 💤 Low value

Global deduplication may hide multi-pod failures.

The deduplication key is only the message text (e['msg']), which means if the same error occurs in multiple pods, only one entry is retained. This could mask systemic issues affecting multiple pods.

Consider including the pod name in the deduplication key if you want to preserve per-pod visibility:

         seen = {}
         for e in raw_entries:
-            key = e['msg']
+            key = (e['pod'], e['msg'])
             if key not in seen or e['ts'] < seen[key]['ts']:
                 seen[key] = e
🤖 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 `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py` around lines 217 - 223,
The deduplication logic in the analyze_lvms function uses only the message text
as the deduplication key, which causes identical errors occurring in multiple
pods to be collapsed into a single entry, masking systemic failures. Modify the
key construction from key = e['msg'] to include both the pod name and message
(such as creating a composite key with e['pod'] and e['msg'] or using a tuple of
both values) to ensure that the same error message is tracked separately per pod
while still deduplicating duplicate entries within the same pod.
🤖 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.

Outside diff comments:
In `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py`:
- Around line 345-359: When a VG node has status 'Progressing' with a reason, it
is being added to both the 'warning' list (at line 347) and the 'critical' list
(at line 359), causing double-counting of the same issue. Modify the condition
that controls whether to append to self.issues['critical'] on line 359 to
exclude 'Progressing' status. The condition currently checks `if reason and st
!= 'Ready':` but should also exclude 'Progressing' by adding an additional check
`and st != 'Progressing'` so that 'Progressing' status items are only added to
warnings, not critical issues.
- Around line 499-518: The issue tracking logic that appends to
self.issues['critical'] and self.issues['warning'] is currently nested inside
the if e['error']: condition, which means error-level entries without an error
field are not tracked in the issues summary. Move the if/else block that checks
e['level'] == 'error' and appends to self.issues outside of the if e['error']:
block so that all error and warning level entries are tracked regardless of
whether the error field is present. The error field display logic can remain
nested, but the issue tracking must execute for every entry that has an error or
warning level.

---

Nitpick comments:
In `@plugins/lvms/skills/analyze/scripts/analyze_lvms.py`:
- Around line 217-223: The deduplication logic in the analyze_lvms function uses
only the message text as the deduplication key, which causes identical errors
occurring in multiple pods to be collapsed into a single entry, masking systemic
failures. Modify the key construction from key = e['msg'] to include both the
pod name and message (such as creating a composite key with e['pod'] and
e['msg'] or using a tuple of both values) to ensure that the same error message
is tracked separately per pod while still deduplicating duplicate entries within
the same pod.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: b7939640-caa4-44fb-9fc0-6def8b0b7470

📥 Commits

Reviewing files that changed from the base of the PR and between ad1ff34 and d598009.

📒 Files selected for processing (1)
  • plugins/lvms/skills/analyze/scripts/analyze_lvms.py

- Fix Progressing VG nodes being double-counted in both warning and
  critical issue lists — only append reason to critical for non-Ready,
  non-Progressing statuses
- Un-nest issue tracking from error field check so error-level log
  entries without an explicit error field are still tracked in summary
- Include pod name in log dedup key so identical errors across different
  pods are preserved separately

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kasturinarra

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 16, 2026
@openshift-merge-bot openshift-merge-bot Bot merged commit 0dd8cde into openshift-eng:main Jun 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants