import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import { DocHeader } from "@/components/ui/doc-header" import { Callout } from "@/components/ui/callout" import CopyableCode from "@/components/CopyableCode" export async function generateMetadata({ params, }: { params: Promise<{ locale: string }> }): Promise { const { locale } = await params const t = await getTranslations({ locale, namespace: "docs.storageShare.hostLocalShared.meta" }) return { title: t("title"), description: t("description"), openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://macrimi.github.io/ProxMenux/docs/storage-share/host-local-shared", }, } } type StringItem = string type BitsRow = { bit: string; effect: string; why: string } type RelatedItem = { href: string; label: string; tail?: string; tailRich?: string } export default async function HostLocalSharedPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.storageShare.hostLocalShared" }) const messages = (await getMessages({ locale })) as unknown as { docs: { storageShare: { hostLocalShared: { why: { items: StringItem[] } bits: { rows: BitsRow[] } related: { items: RelatedItem[] } } } } } const whyItems = messages.docs.storageShare.hostLocalShared.why.items const bitsRows = messages.docs.storageShare.hostLocalShared.bits.rows const relatedItems = messages.docs.storageShare.hostLocalShared.related.items const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const kbd = (chunks: React.ReactNode) => {chunks} const mountLink = (chunks: React.ReactNode) => ( {chunks} ) const diskLink = (chunks: React.ReactNode) => ( {chunks} ) return (
{t.rich("intro.body", { strong, code, mountLink })}

{t("why.heading")}

{t("why.intro")}

    {whyItems.map((_, idx) => (
  • {t.rich(`why.items.${idx}`, { strong })}
  • ))}

{t.rich("why.outro", { strong })}

{t("howRuns.heading")}

{t.rich("howRuns.body", { strong })}

{`┌─────────────────────────────────────────────┐
│  PHASE 1 — Pick the target path             │
│  (nothing touched yet)                      │
└──────────────────┬──────────────────────────┘
                   ▼
      Location picker (4 options)
      ├─ 1. Create new folder in /mnt
      │       ProxMenux suggests a free name
      │       ("shared", "shared2", "shared3"…)
      ├─ 2. Enter custom path
      │       Any absolute path on the host
      ├─ 3. View existing folders in /mnt
      │       Read-only summary (perms, owner,
      │       free space) then back to menu
      └─ 4. Cancel
                   │
                   ▼
      Path validation
      └─ Must start with "/" (absolute path)
         Non-absolute → reject, re-ask
                   │
                   ▼
      Existing directory?
      └─ If /mnt/ already exists, ask
         "Continue with permission setup?"
         (adjusting existing dir is allowed)
                   │
   ┌──────── Cancel   OR   Confirm ────┐
   ▼                                   ▼
Exit, nothing        ┌─────────────────┴─────────────────┐
was changed          │  PHASE 2 — Create + set perms      │
                     └─────────────────┬─────────────────┘
                                       ▼
                       mkdir -p 
                                       ▼
                       chown root:root 
                                       ▼
                       chmod 1777 
                        (sticky bit + world-rwx)
                                       ▼
                       chmod -R a+rwX 
                        (existing content stays accessible;
                         X = execute only on directories)
                                       ▼
                       find  -type d \\
                            -exec chmod 1777 {} +
                        (propagate sticky bit to subdirs)
                                       ▼
                       setfacl -b -R 
                        (remove any restrictive ACLs)
                                       ▼
                       setfacl -R -m u::rwx,g::rwx,o::rwx,m::rwx
                        (explicit rwx for user/group/other/mask)
                                       ▼
                       setfacl -R -m d:u::rwx,d:g::rwx,...
                        (default ACLs so NEW files inherit rwx)
                                       ▼
                       Register in ProxMenux share map
                        (pmx_share_map_set  "open")
                                       ▼
                       Summary:
                       • directory path
                       • permissions: 1777 (rwxrwxrwt)
                       • owner: root:root
                       • ACL: open rwx + default inheritance
                       • profile: works with priv and
                         unprivileged LXCs`}
      

{t("bits.heading")}

{t.rich("bits.intro", { strong, code })}

{bitsRows.map((row) => ( ))}
{t("bits.headerBit")} {t("bits.headerEffect")} {t("bits.headerWhy")}
{row.bit} {row.effect} {row.why}
{t.rich("bits.privBody", { code })}

{t("where.heading")}

{t("where.intro")}

{t("where.opt1Title")}

{t.rich("where.opt1Body", { code })}

{t("where.opt2Title")}

{t.rich("where.opt2Body", { code })}

{t("where.opt3Title")}

{t.rich("where.opt3Body", { code })}

{t("where.opt4Title")}

{t.rich("where.opt4Body", { kbd })}

{t.rich("where.tipBody", { code, diskLink })}

{t("manual.heading")}

{t("manual.body")}

{t("next.heading")}

{t.rich("next.body", { strong, code, mountLink })}

{t("troubleshoot.heading")}

{t.rich("troubleshoot.mkdirBody", { code })} {t.rich("troubleshoot.writeBody", { code })} {t.rich("troubleshoot.aclBody", { code })}

{t("related.heading")}

    {relatedItems.map((item, idx) => (
  • {item.label} {item.tailRich ? t.rich(`related.items.${idx}.tailRich`, { code }) : item.tail}
  • ))}
) }