Compare commits

..

9 Commits

Author SHA1 Message Date
community-scripts-pr-app[bot]
4003aad7d5 Update CHANGELOG.md (#9384)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-23 12:23:36 +00:00
community-scripts-pr-app[bot]
b9809d6768 Update CHANGELOG.md (#9383)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-23 12:23:17 +00:00
community-scripts-pr-app[bot]
70d59b825c Update date in json (#9382)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-11-23 12:23:14 +00:00
Alpha Vylly
72a39012b6 feat: add script disable functionality with visual indicators (#9374) 2025-11-23 13:22:57 +01:00
community-scripts-pr-app[bot]
4134f68fb4 Update versions.json (#9381)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-23 13:05:10 +01:00
community-scripts-pr-app[bot]
c9e7662c5c Update CHANGELOG.md (#9380)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-23 11:05:56 +00:00
Rick Johnson
4d6fa0a73d [LibreNMS] Correcting mariadb sed string for Debian 13 default in install/librenms-install.sh, website config for Debian 13 #9369 (#9370)
* Correcting mariadb config string sed modification to match mariadb provided in Debian 13

* Correcting Debian version for LibreNMS to 13 to match installation script.
2025-11-23 12:05:35 +01:00
community-scripts-pr-app[bot]
84412d9d9c Update CHANGELOG.md (#9379)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-23 11:00:36 +00:00
Tobias
581fed294f Update glpi-install.sh to remove install.php (#9378) 2025-11-23 12:00:10 +01:00
12 changed files with 258 additions and 83 deletions

View File

@@ -16,8 +16,19 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- [LibreNMS] Correcting mariadb sed string for Debian 13 default in install/librenms-install.sh, website config for Debian 13 #9369 [@htmlspinnr](https://github.com/htmlspinnr) ([#9370](https://github.com/community-scripts/ProxmoxVE/pull/9370))
- fix: Snipe-IT update check failure [@ruanmed](https://github.com/ruanmed) ([#9371](https://github.com/community-scripts/ProxmoxVE/pull/9371)) - fix: Snipe-IT update check failure [@ruanmed](https://github.com/ruanmed) ([#9371](https://github.com/community-scripts/ProxmoxVE/pull/9371))
- #### 🔧 Refactor
- Update glpi-install.sh to remove install.php [@CrazyWolf13](https://github.com/CrazyWolf13) ([#9378](https://github.com/community-scripts/ProxmoxVE/pull/9378))
### 🌐 Website
- #### ✨ New Features
- feat(frontend): add script disable functionality with visual indicators [@AlphaLawless](https://github.com/AlphaLawless) ([#9374](https://github.com/community-scripts/ProxmoxVE/pull/9374))
## 2025-11-22 ## 2025-11-22
### 🆕 New Scripts ### 🆕 New Scripts

View File

@@ -23,7 +23,7 @@
"ram": 2048, "ram": 2048,
"hdd": 4, "hdd": 4,
"os": "Debian", "os": "Debian",
"version": "12" "version": "13"
} }
} }
], ],

View File

@@ -0,0 +1,43 @@
{
"name": "OPNsense",
"slug": "opnsense-vm",
"categories": [
4,
2
],
"date_created": "2025-11-23",
"type": "vm",
"updateable": true,
"privileged": false,
"interface_port": 443,
"documentation": "https://docs.opnsense.org/",
"website": "https://opnsense.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/opnsense.webp",
"config_path": "",
"description": "OPNsense is an open-source firewall and routing platform based on FreeBSD. It provides advanced security features, including intrusion detection, VPN support, traffic shaping, and web filtering, with an intuitive web interface for easy management. Known for its reliability and regular updates, OPNsense is a popular choice for both businesses and home networks.",
"disable": true,
"disable_description": "This script has been temporarily disabled due to installation failures. The OPNsense bootstrap process was not completing successfully, resulting in a plain FreeBSD VM instead of a functional OPNsense installation. The issue is being investigated and the script will be re-enabled once resolved. For more details, see: https://github.com/community-scripts/ProxmoxVE/issues/6183",
"install_methods": [
{
"type": "default",
"script": "vm/opnsense-vm.sh",
"resources": {
"cpu": 4,
"ram": 8192,
"hdd": 10,
"os": "FreeBSD",
"version": "latest"
}
}
],
"default_credentials": {
"username": "root",
"password": "opnsense"
},
"notes": [
{
"text": "It will fail with default settings if there is no vmbr0 and vmbr1 on your node. Use advanced settings in this case.",
"type": "warning"
}
]
}

View File

@@ -1,4 +1,54 @@
[ [
{
"name": "rcourtman/Pulse",
"version": "v4.32.4",
"date": "2025-11-23T11:05:14Z"
},
{
"name": "readeck/readeck",
"version": "0.21.2",
"date": "2025-11-23T10:56:43Z"
},
{
"name": "verdaccio/verdaccio",
"version": "generator-verdaccio-plugin@6.0.0-next-8.26",
"date": "2025-11-23T07:46:06Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.340",
"date": "2025-11-23T06:00:18Z"
},
{
"name": "tobychui/zoraxy",
"version": "v3.3.0-rc1",
"date": "2025-11-23T05:42:35Z"
},
{
"name": "hyperion-project/hyperion.ng",
"version": "2.1.1",
"date": "2025-06-14T17:45:06Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.80.5.rc.2",
"date": "2025-11-23T00:31:24Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.0.1",
"date": "2025-10-15T16:53:55Z"
},
{
"name": "jeedom/core",
"version": "4.4.20",
"date": "2025-11-23T00:27:04Z"
},
{ {
"name": "paperless-ngx/paperless-ngx", "name": "paperless-ngx/paperless-ngx",
"version": "v2.20.0", "version": "v2.20.0",
@@ -39,6 +89,11 @@
"version": "v14.2.0", "version": "v14.2.0",
"date": "2025-11-22T12:54:08Z" "date": "2025-11-22T12:54:08Z"
}, },
{
"name": "keycloak/keycloak",
"version": "26.4.5",
"date": "2025-11-12T15:24:23Z"
},
{ {
"name": "pocketbase/pocketbase", "name": "pocketbase/pocketbase",
"version": "v0.34.0", "version": "v0.34.0",
@@ -59,36 +114,16 @@
"version": "1.1.5", "version": "1.1.5",
"date": "2025-11-22T07:02:52Z" "date": "2025-11-22T07:02:52Z"
}, },
{
"name": "Jackett/Jackett",
"version": "v0.24.339",
"date": "2025-11-22T06:05:53Z"
},
{ {
"name": "theonedev/onedev", "name": "theonedev/onedev",
"version": "v13.1.0", "version": "v13.1.0",
"date": "2025-11-22T04:29:25Z" "date": "2025-11-22T04:29:25Z"
}, },
{
"name": "jeedom/core",
"version": "4.4.20",
"date": "2025-11-22T00:27:05Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.0.1",
"date": "2025-10-15T16:53:55Z"
},
{ {
"name": "TwiN/gatus", "name": "TwiN/gatus",
"version": "v5.33.0", "version": "v5.33.0",
"date": "2025-11-21T22:54:49Z" "date": "2025-11-21T22:54:49Z"
}, },
{
"name": "BerriAI/litellm",
"version": "v1.78.5-stable-patch-1",
"date": "2025-11-21T19:57:45Z"
},
{ {
"name": "homarr-labs/homarr", "name": "homarr-labs/homarr",
"version": "v1.44.0", "version": "v1.44.0",
@@ -104,16 +139,6 @@
"version": "v1.72.0", "version": "v1.72.0",
"date": "2025-11-21T18:20:58Z" "date": "2025-11-21T18:20:58Z"
}, },
{
"name": "keycloak/keycloak",
"version": "26.4.5",
"date": "2025-11-12T15:24:23Z"
},
{
"name": "readeck/readeck",
"version": "0.21.1",
"date": "2025-11-21T17:17:52Z"
},
{ {
"name": "mattermost/mattermost", "name": "mattermost/mattermost",
"version": "v10.11.8", "version": "v10.11.8",
@@ -154,11 +179,6 @@
"version": "v0.23.0-alpha.24", "version": "v0.23.0-alpha.24",
"date": "2025-11-21T12:16:39Z" "date": "2025-11-21T12:16:39Z"
}, },
{
"name": "rcourtman/Pulse",
"version": "v4.32.3",
"date": "2025-11-21T11:16:25Z"
},
{ {
"name": "seriousm4x/UpSnap", "name": "seriousm4x/UpSnap",
"version": "5.2.4", "version": "5.2.4",
@@ -189,11 +209,6 @@
"version": "mariadb-12.1.2", "version": "mariadb-12.1.2",
"date": "2025-11-18T15:16:21Z" "date": "2025-11-18T15:16:21Z"
}, },
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
},
{ {
"name": "bluenviron/mediamtx", "name": "bluenviron/mediamtx",
"version": "v1.15.4", "version": "v1.15.4",
@@ -359,11 +374,6 @@
"version": "v1.143.0rc1", "version": "v1.143.0rc1",
"date": "2025-11-19T00:09:31Z" "date": "2025-11-19T00:09:31Z"
}, },
{
"name": "hyperion-project/hyperion.ng",
"version": "2.1.1",
"date": "2025-06-14T17:45:06Z"
},
{ {
"name": "gtsteffaniak/filebrowser", "name": "gtsteffaniak/filebrowser",
"version": "v1.0.1-stable", "version": "v1.0.1-stable",
@@ -529,11 +539,6 @@
"version": "v4.7.0", "version": "v4.7.0",
"date": "2025-11-14T09:45:13Z" "date": "2025-11-14T09:45:13Z"
}, },
{
"name": "verdaccio/verdaccio",
"version": "generator-verdaccio-plugin@6.0.0-next-8.25",
"date": "2025-11-14T08:14:55Z"
},
{ {
"name": "runtipi/runtipi", "name": "runtipi/runtipi",
"version": "v4.6.5", "version": "v4.6.5",
@@ -834,11 +839,6 @@
"version": "v1.9.1", "version": "v1.9.1",
"date": "2025-11-02T21:14:50Z" "date": "2025-11-02T21:14:50Z"
}, },
{
"name": "tobychui/zoraxy",
"version": "v3.2.9",
"date": "2025-11-02T05:48:39Z"
},
{ {
"name": "9001/copyparty", "name": "9001/copyparty",
"version": "v1.19.20", "version": "v1.19.20",

View File

@@ -35,12 +35,22 @@ export const ScriptSchema = z.object({
logo: z.string().url().nullable(), logo: z.string().url().nullable(),
config_path: z.string(), config_path: z.string(),
description: z.string().min(1, "Description is required"), description: z.string().min(1, "Description is required"),
disable: z.boolean().optional(),
disable_description: z.string().optional(),
install_methods: z.array(InstallMethodSchema).min(1, "At least one install method is required"), install_methods: z.array(InstallMethodSchema).min(1, "At least one install method is required"),
default_credentials: z.object({ default_credentials: z.object({
username: z.string().nullable(), username: z.string().nullable(),
password: z.string().nullable(), password: z.string().nullable(),
}), }),
notes: z.array(NoteSchema), notes: z.array(NoteSchema),
}).refine((data) => {
if (data.disable === true && !data.disable_description) {
return false;
}
return true;
}, {
message: "disable_description is required when disable is true",
path: ["disable_description"],
}); });
export type Script = z.infer<typeof ScriptSchema>; export type Script = z.infer<typeof ScriptSchema>;

View File

@@ -42,6 +42,8 @@ const initialScript: Script = {
website: null, website: null,
logo: null, logo: null,
description: "", description: "",
disable: undefined,
disable_description: undefined,
install_methods: [], install_methods: [],
default_credentials: { default_credentials: {
username: null, username: null,
@@ -261,7 +263,25 @@ export default function JSONGenerator() {
<Switch checked={script.privileged} onCheckedChange={checked => updateScript("privileged", checked)} /> <Switch checked={script.privileged} onCheckedChange={checked => updateScript("privileged", checked)} />
<label>Privileged</label> <label>Privileged</label>
</div> </div>
<div className="flex items-center space-x-2">
<Switch checked={script.disable || false} onCheckedChange={checked => updateScript("disable", checked)} />
<label>Disabled</label>
</div>
</div> </div>
{script.disable && (
<div>
<Label>
Disable Description
{" "}
<span className="text-red-500">*</span>
</Label>
<Textarea
placeholder="Explain why this script is disabled..."
value={script.disable_description || ""}
onChange={e => updateScript("disable_description", e.target.value)}
/>
</div>
)}
<Input <Input
placeholder="Interface Port" placeholder="Interface Port"
type="number" type="number"

View File

@@ -123,7 +123,7 @@ export default function ScriptAccordion({
className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${selectedScript === script.slug className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${selectedScript === script.slug
? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white" ? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white"
: "" : ""
}`} } ${script.disable ? "opacity-60" : ""}`}
onClick={() => { onClick={() => {
handleSelected(script.slug); handleSelected(script.slug);
setSelectedCategory(category.name); setSelectedCategory(category.name);
@@ -143,7 +143,9 @@ export default function ScriptAccordion({
alt={script.name} alt={script.name}
className="mr-1 w-4 h-4 rounded-full" className="mr-1 w-4 h-4 rounded-full"
/> />
<span className="flex items-center gap-2">{script.name}</span> <span className="flex items-center gap-2">
{script.name}
</span>
</div> </div>
{formattedBadge(script.type)} {formattedBadge(script.type)}
</Link> </Link>

View File

@@ -12,6 +12,7 @@ import { useVersions } from "@/hooks/use-versions";
import { basePath } from "@/config/site-config"; import { basePath } from "@/config/site-config";
import { extractDate } from "@/lib/time"; import { extractDate } from "@/lib/time";
import DisableDescription from "./script-items/disable-description";
import { getDisplayValueFromType } from "./script-info-blocks"; import { getDisplayValueFromType } from "./script-info-blocks";
import DefaultPassword from "./script-items/default-password"; import DefaultPassword from "./script-items/default-password";
import InstallCommand from "./script-items/install-command"; import InstallCommand from "./script-items/install-command";
@@ -146,37 +147,45 @@ export function ScriptItem({ item, setSelectedScript }: ScriptItemProps) {
<ScriptHeader item={item} /> <ScriptHeader item={item} />
</Suspense> </Suspense>
<Description item={item} /> {item.disable && item.disable_description && (
<Alerts item={item} /> <DisableDescription item={item} />
) }
<div className="mt-4 rounded-lg border shadow-sm"> {!item.disable && (
<div className="flex gap-3 px-4 py-2 bg-accent/25"> <>
<h2 className="text-lg font-semibold"> <Description item={item} />
How to
{" "} <Alerts item={item} />
{item.type === "pve" ? "use" : item.type === "addon" ? "apply" : "install"} <div className="mt-4 rounded-lg border shadow-sm">
</h2>
<Tooltips item={item} />
</div>
<Separator />
<div className="">
<InstallCommand item={item} />
</div>
{item.config_path && (
<>
<Separator />
<div className="flex gap-3 px-4 py-2 bg-accent/25"> <div className="flex gap-3 px-4 py-2 bg-accent/25">
<h2 className="text-lg font-semibold">Location of config file</h2> <h2 className="text-lg font-semibold">
How to
{" "}
{item.type === "pve" ? "use" : item.type === "addon" ? "apply" : "install"}
</h2>
<Tooltips item={item} />
</div> </div>
<Separator /> <Separator />
<div className=""> <div className="">
<ConfigFile configPath={item.config_path} /> <InstallCommand item={item} />
</div> </div>
</> {item.config_path && (
)} <>
</div> <Separator />
<div className="flex gap-3 px-4 py-2 bg-accent/25">
<h2 className="text-lg font-semibold">Location of config file</h2>
</div>
<Separator />
<div className="">
<ConfigFile configPath={item.config_path} />
</div>
</>
)}
</div>
<DefaultPassword item={item} /> <DefaultPassword item={item} />
</>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,26 @@
import { AlertCircle } from "lucide-react";
import type { Script } from "@/lib/types";
import TextParseLinks from "@/components/text-parse-links";
import { AlertColors } from "@/config/site-config";
import { cn } from "@/lib/utils";
export default function DisableDescription({ item }: { item: Script }) {
return (
<div className="mt-4 flex flex-col shadow-sm gap-2">
<div
className={cn(
"flex items-start gap-3 rounded-lg border p-4 text-sm",
AlertColors.warning,
)}
>
<AlertCircle className="h-5 min-h-5 w-5 min-w-5 mt-0.5" />
<div className="flex flex-col gap-2">
<h3 className="font-semibold text-base">Script Disabled</h3>
<p>{TextParseLinks(item.disable_description!)}</p>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,52 @@
import { ClipboardIcon, ExternalLink } from "lucide-react";
import { Fragment } from "react";
import handleCopy from "./handle-copy";
const URL_PATTERN = /(https?:\/\/[^\s,]+)/;
const CODE_PATTERN = /`([^`]*)`/;
export default function TextParseLinks(text: string) {
const codeParts = text.split(CODE_PATTERN);
return codeParts.map((part: string, codeIndex: number) => {
if (codeIndex % 2 === 1) {
return (
<span
key={`code-${codeIndex}`}
className="bg-secondary py-1 px-2 rounded-lg inline-flex items-center gap-2"
>
{part}
<ClipboardIcon
className="size-3 cursor-pointer"
onClick={() => handleCopy("command", part)}
/>
</span>
);
}
const urlParts = part.split(URL_PATTERN);
return (
<Fragment key={`text-${codeIndex}`}>
{urlParts.map((urlPart: string, urlIndex: number) => {
if (urlIndex % 2 === 1) {
return (
<a
key={`url-${codeIndex}-${urlIndex}`}
href={urlPart}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-blue-600 dark:text-blue-400 hover:underline font-medium transition-colors"
>
{urlPart}
<ExternalLink className="size-3" />
</a>
);
}
return <Fragment key={`plain-${codeIndex}-${urlIndex}`}>{urlPart}</Fragment>;
})}
</Fragment>
);
});
}

View File

@@ -14,6 +14,8 @@ export type Script = {
logo: string | null; logo: string | null;
config_path: string; config_path: string;
description: string; description: string;
disable?: boolean;
disable_description?: string;
install_methods: { install_methods: {
type: "default" | "alpine"; type: "default" | "alpine";
script: string; script: string;

View File

@@ -65,7 +65,7 @@ chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenm
msg_ok "Configured LibreNMS" msg_ok "Configured LibreNMS"
msg_info "Configure MariaDB" msg_info "Configure MariaDB"
sed -i "/\[mysqld\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf sed -i "/\[mariadb\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl enable -q --now mariadb systemctl enable -q --now mariadb
msg_ok "Configured MariaDB" msg_ok "Configured MariaDB"