<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Scope preserved NFS no_root_squash warning to image staging export]]></title><description><![CDATA[<p dir="auto">Summary<br />
When STORAGE_rebuild_nfs_exports != yes, configureNFS() currently warns if no_root_squash appears anywhere in /etc/exports.</p>
<p dir="auto">That produces a false warning when /images/dev is already configured correctly with all_squash,anonuid=…,anongid=…, but an unrelated read-only export (for example a mounted Linux ISO tree) intentionally uses no_root_squash.<br />
Change<br />
Add nfsDevExportHasNoRootSquash() and scope the check to exactly:</p>
<p dir="auto">${STORAGE_image_share_path}/dev</p>
<p dir="auto">The warning still appears when the image staging export itself uses no_root_squash, but unrelated exports no longer trigger it.<br />
Regression coverage<br />
tests/nfs-preserved-exports-warning.test.sh covers:</p>
<ul>
<li>safe /images/dev plus an ISO export using no_root_squash -&gt; no warning condition</li>
<li>/images/dev using no_root_squash -&gt; warning condition</li>
<li>similarly named paths and commented lines -&gt; ignored</li>
<li>configureNFS() actually uses the scoped helper<br />
Reproduction<br />
Example preserved exports:</li>
</ul>
<p dir="auto">/images *(ro,sync,no_wdelay,subtree_check,insecure_locks,all_squash,anonuid=1002,anongid=1002,fsid=0)<br />
/images/dev *(rw,async,no_wdelay,subtree_check,all_squash,anonuid=1002,anongid=1002,fsid=1)<br />
/var/www/html/ISO/Ubuntu/26.04X64/ *(ro,sync,no_wdelay,insecure_locks,no_root_squash,insecure)</p>
<p dir="auto">The existing global grep -q “no_root_squash” “$nfsconfig” reports that captures land as root even though the /images/dev export is already ownership-safe.</p>
<p dir="auto">diff --git a/lib/common/functions.sh b/lib/common/functions.sh<br />
— a/lib/common/functions.sh<br />
+++ b/lib/common/functions.sh<br />
@@ -1,3 +1,14 @@<br />
+nfsDevExportHasNoRootSquash() {</p>
<ul>
<li>local config=“$1”</li>
<li>local devpath=“${STORAGE_image_share_path%/}/dev”</li>
<li>&lsqb;&lsqb; -f “$config” &rsqb;&rsqb; || return 1</li>
<li>awk -v path=“$devpath” ’</li>
<li>
<pre><code>   $1 == path &amp;&amp; /(^|[,(])no_root_squash([,)]|$)/ {
</code></pre>
</li>
<li>
<pre><code>       found=1
</code></pre>
</li>
<li>
<pre><code>   }
</code></pre>
</li>
<li>
<pre><code>   END { exit !found }
</code></pre>
</li>
<li>’ “$config”<br />
+}<br />
configureNFS() {<br />
dots “Setting up NFS configuration file”<br />
if &lsqb;&lsqb; -f “/etc/nfs.conf” &rsqb;&rsqb;; then<br />
@@ -25,7 +36,7 @@<br />
dots “Setting up exports file”<br />
if &lsqb;&lsqb; ${STORAGE_rebuild_nfs_exports} != yes &rsqb;&rsqb;; then<br />
echo “Skipped”</li>
</ul>
<ul>
<li>
<pre><code>   if &lsqb;&lsqb; -f "$nfsconfig" &rsqb;&rsqb; &amp;&amp; grep -q "no_root_squash" "$nfsconfig"; then
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code>   if nfsDevExportHasNoRootSquash "$nfsconfig"; then
       echo
       echo "  ** WARNING: ${nfsconfig} still exports with no_root_squash."
       echo "  ** Captures land as root, so moving the image out of"
</code></pre>
</li>
</ul>
<p dir="auto">diff --git a/tests/nfs-preserved-exports-warning.test.sh b/tests/nfs-preserved-exports-warning.test.sh<br />
new file mode 100755<br />
— /dev/null<br />
+++ b/tests/nfs-preserved-exports-warning.test.sh<br />
@@ -0,0 +1,89 @@<br />
+#!/bin/bash<br />
+#<br />
+# The preserved-exports warning must only inspect the image staging export.<br />
+# An unrelated read-only ISO export may intentionally use no_root_squash and<br />
+# must not make FOG claim that /images/dev will capture files as root.<br />
+#<br />
+# Usage: bash tests/nfs-preserved-exports-warning.test.sh<br />
+<br />
+root=$(cd – “$(dirname – “${BASH_SOURCE[0]}”)/…” &amp;&amp; pwd)<br />
+functions=“$root/lib/common/functions.sh”<br />
+<br />
+pass=0<br />
+fail=0<br />
+<br />
+pass_case() {</p>
<ul>
<li>pass=$((pass + 1))<br />
+}</li>
<li></li>
</ul>
<p dir="auto">+fail_case() {</p>
<ul>
<li>fail=$((fail + 1))</li>
<li>printf ’  FAIL  %s\n’ “$1”<br />
+}</li>
<li></li>
</ul>
<p dir="auto">+if &lsqb;&lsqb; ! -r $functions &rsqb;&rsqb;; then</p>
<ul>
<li>echo “FAIL: cannot read $functions” &gt;&amp;2</li>
<li>exit 1<br />
+fi</li>
<li></li>
</ul>
<p dir="auto">+# Load only the helper under test. Sourcing all of <a href="http://functions.sh" target="_blank" rel="noopener noreferrer nofollow ugc">functions.sh</a> would make<br />
+# this small unit test depend on the installer’s global setup.<br />
+helper=$(</p>
<ul>
<li>awk ’</li>
<li>
<pre><code>   /^nfsDevExportHasNoRootSquash\(\) \{/ { emit=1 }
</code></pre>
</li>
<li>
<pre><code>   emit { print }
</code></pre>
</li>
<li>
<pre><code>   emit &amp;&amp; /^}/ { exit }
</code></pre>
</li>
<li>’ “$functions”<br />
+)<br />
+if &lsqb;&lsqb; -z $helper &rsqb;&rsqb;; then</li>
<li>echo “FAIL: nfsDevExportHasNoRootSquash() not found” &gt;&amp;2</li>
<li>exit 1<br />
+fi<br />
+eval “$helper”</li>
<li></li>
</ul>
<p dir="auto">+tmp=$(mktemp)<br />
+trap ‘rm -f “$tmp”’ EXIT<br />
+STORAGE_image_share_path=/images<br />
+<br />
+cat &gt; “$tmp” &lt;&lt;‘EOF_CASE’<br />
+/images *(ro,sync,all_squash,anonuid=1002,anongid=1002,fsid=0)<br />
+/images/dev *(rw,async,all_squash,anonuid=1002,anongid=1002,fsid=1)<br />
+/var/www/html/ISO/Ubuntu/26.04X64/ *(ro,sync,no_root_squash,insecure)<br />
+EOF_CASE<br />
+if nfsDevExportHasNoRootSquash “$tmp”; then</p>
<ul>
<li>fail_case “unrelated ISO no_root_squash does not trigger warning”<br />
+else</li>
<li>pass_case<br />
+fi</li>
<li></li>
</ul>
<p dir="auto">+cat &gt; “$tmp” &lt;&lt;‘EOF_CASE’<br />
+/images *(ro,sync,all_squash,anonuid=1002,anongid=1002,fsid=0)<br />
+/images/dev *(rw,async,no_root_squash,fsid=1)<br />
+EOF_CASE<br />
+if nfsDevExportHasNoRootSquash “$tmp”; then</p>
<ul>
<li>pass_case<br />
+else</li>
<li>fail_case “/images/dev no_root_squash triggers warning”<br />
+fi</li>
<li></li>
</ul>
<p dir="auto">+cat &gt; “$tmp” &lt;&lt;‘EOF_CASE’<br />
+/images/dev *(rw,async,all_squash,anonuid=1002,anongid=1002,fsid=1)<br />
+/images-old/dev *(rw,async,no_root_squash,fsid=2)<br />
+# /images/dev *(rw,no_root_squash)<br />
+EOF_CASE<br />
+if nfsDevExportHasNoRootSquash “$tmp”; then</p>
<ul>
<li>fail_case “prefix paths and comments do not trigger warning”<br />
+else</li>
<li>pass_case<br />
+fi</li>
<li></li>
</ul>
<p dir="auto">+if ! grep -q ‘if nfsDevExportHasNoRootSquash “$nfsconfig”; then’ “$functions”; then</p>
<ul>
<li>echo "  FAIL  configureNFS does not use nfsDevExportHasNoRootSquash" &gt;&amp;2</li>
<li>fail=$((fail + 1))<br />
+else</li>
<li>pass=$((pass + 1))<br />
+fi</li>
<li></li>
</ul>
<p dir="auto">+echo “ok $pass”<br />
+&lsqb;&lsqb; $fail -eq 0 &rsqb;&rsqb; || { echo “FAIL ($fail of $((pass + fail)))” &gt;&amp;2; exit 1; }<br />
+exit 0</p>
]]></description><link>http://forums.fogproject.org/topic/18293/scope-preserved-nfs-no_root_squash-warning-to-image-staging-export</link><generator>RSS for Node</generator><lastBuildDate>Wed, 28 Oct 2026 10:22:28 GMT</lastBuildDate><atom:link href="http://forums.fogproject.org/topic/18293.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 28 Oct 2026 09:02:12 GMT</pubDate><ttl>60</ttl></channel></rss>