* feat: support dynamic module build for OpenResty
* feat: add dynamic module build page for OpenResty
* refactor: drop auto fallback, gate dynamic build by version support
- remove auto-to-static fallback; dynamic build failure now reports the
error and hints switching to static build manually
- gate dynamic builds on module support files (Dockerfile.modules +
module.catalog.json) instead of version numbers, expose
dynamicSupported in the modules API
- collect repeated path/status/operate strings into constants
- move nginx module regex patterns into utils/re with semantic helpers
- reorganize nginx_module.go around the main build flows and inline
single-use thin helpers
* feat: limit nginx module build mode options by version support
- build mode radio offers only dynamic and static (auto maps to dynamic
for legacy data)
- disable the dynamic option with a hint when the installed OpenResty
version lacks dynamic build support
* feat: complete i18n for nginx module pages
Fill in the new nginx module keys for all eleven language files
(translations other than zh/en are draft machine translations).
* feat: probe dynamic module support on load and drop the auto build mode
- probe each non-static module's configure params when loading the
module list and report dynamicSupport=supported/unsupported up front
- normalize the legacy auto build mode to dynamic
* feat: clarify module build modes in the UI
- build drawer lists dynamic modules (tagged, hot-reload) and static
modules (tagged, full rebuild + container restart) separately
- disable the dynamic option per module when its params do not support
dynamic build, distinct from the version gate hint
- drop the auto build mode wording everywhere and sync all eleven
language files
* feat: clarify purpose of the nginx module build drawer
- add a purpose hint explaining dynamic (hot reload) vs static (full
rebuild + container restart)
- drop the per-module mode tags now that section headers carry the
semantics
- allow submitting with zero dynamic modules selected when static
modules are present, so static-only users can trigger a build
* feat: pass apt mirror through to dynamic module builds
The mirror selected in the build dialog (or CONTAINER_PACKAGE_URL in the
app env as fallback) is now forwarded as a build arg so the module
builder uses the same apt source as the static build path. test-builder
gains a --mirror option.
* feat: add Lao translations for nginx module pages
cmd.Which() previously shelled out to `which <name>` to determine whether
a binary was on PATH. On distributions that do not ship a `which` package
by default — Arch Linux is the canonical example, but the same applies to
several minimal container images — `which` itself is missing, so every
call to Which() returned false and 1Panel reported core dependencies
(notably Docker) as 'not installed' even when they were running normally.
Switch the primary path to Go's exec.LookPath, which uses the process
PATH directly and has no external dependency. The original shell-out is
preserved as a fallback so any environment where the agent's PATH
differs from the user's interactive shell PATH (the original reason the
shell-out existed) keeps working unchanged.
Both copies are updated (agent/utils/cmd/cmd.go and core/utils/cmd/cmd.go)
and a small unit test is added to each package to guard the regression.
Fixes#12605
Signed-off-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com>
Enabling Panel SSL with the self-sign provider rejected IPv6 hosts with
"domain format invalid". Two coupled bugs caused this:
1. The frontend extracted the host from window.location.href with
href.split('//')[1].split(':')[0]. For an IPv6 URL like
https://[::1]:1234 that yields '[' \u2014 not a valid host \u2014 because
the second split splits on the first colon inside the bracketed
address. Use window.location.hostname, which natively returns the
bracket-stripped IPv6 host.
2. The backend ObtainSSL flow used net.ParseIP(domain) directly. Even if
the frontend sent the bracketed form ('[::1]'), net.ParseIP rejects
brackets, so the value flowed into IsValidDomain() and failed the
regex.
Add common.ParseIPLoose() that accepts both bare and bracketed IPv6 in
addition to bare IPv4. Use it at both call sites in ObtainSSL (renew
path and create path). A unit test guards the regression.
Files:
- agent/utils/common/common.go (new ParseIPLoose helper)
- agent/utils/common/parse_ip_test.go (12 cases, all green)
- agent/app/service/website_ca.go (call sites switched)
- frontend/src/views/setting/safe/ssl/index.vue
(host extraction fix)
Fixes#12646
Signed-off-by: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com>