mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-03 20:03:25 +01:00
Compare commits
4 Commits
disable_np
...
pr-update-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03f6c5557e | ||
|
|
ea264f673b | ||
|
|
3f769c6492 | ||
|
|
742248dabd |
@@ -778,6 +778,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- KitchenOwl ([#11453](https://github.com/community-scripts/ProxmoxVE/pull/11453))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- cleanup(frontend): remove unused /category-view route [@ls-root](https://github.com/ls-root) ([#11461](https://github.com/community-scripts/ProxmoxVE/pull/11461))
|
||||
|
||||
## 2026-02-01
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
51
ct/alpine-rustypaste.sh
Normal file
51
ct/alpine-rustypaste.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/orhun/rustypaste
|
||||
|
||||
APP="Alpine-RustyPaste"
|
||||
var_tags="${var_tags:-alpine;pastebin;storage}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-256}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-alpine}"
|
||||
var_version="${var_version:-3.23}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if ! apk info -e rustypaste >/dev/null 2>&1; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating RustyPaste"
|
||||
$STD apk update
|
||||
$STD apk upgrade rustypaste --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
|
||||
msg_ok "Updated RustyPaste"
|
||||
|
||||
msg_info "Restarting Services"
|
||||
$STD rc-service rustypaste restart
|
||||
msg_ok "Restarted Services"
|
||||
msg_ok "Updated successfully!"
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
||||
6
ct/headers/alpine-rustypaste
Normal file
6
ct/headers/alpine-rustypaste
Normal file
@@ -0,0 +1,6 @@
|
||||
___ __ _ ____ __ ____ __
|
||||
/ | / /___ (_)___ ___ / __ \__ _______/ /___ __/ __ \____ ______/ /____
|
||||
/ /| | / / __ \/ / __ \/ _ \______/ /_/ / / / / ___/ __/ / / / /_/ / __ `/ ___/ __/ _ \
|
||||
/ ___ |/ / /_/ / / / / / __/_____/ _, _/ /_/ (__ ) /_/ /_/ / ____/ /_/ (__ ) /_/ __/
|
||||
/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_|\__,_/____/\__/\__, /_/ \__,_/____/\__/\___/
|
||||
/_/ /____/
|
||||
6
ct/headers/rustypaste
Normal file
6
ct/headers/rustypaste
Normal file
@@ -0,0 +1,6 @@
|
||||
__ __
|
||||
_______ _______/ /___ ______ ____ ______/ /____
|
||||
/ ___/ / / / ___/ __/ / / / __ \/ __ `/ ___/ __/ _ \
|
||||
/ / / /_/ (__ ) /_/ /_/ / /_/ / /_/ (__ ) /_/ __/
|
||||
/_/ \__,_/____/\__/\__, / .___/\__,_/____/\__/\___/
|
||||
/____/_/
|
||||
69
ct/rustypaste.sh
Normal file
69
ct/rustypaste.sh
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: GoldenSpringness
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/orhun/rustypaste
|
||||
|
||||
APP="rustypaste"
|
||||
var_tags="${var_tags:-pastebin;storage}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-20}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f /opt/rustypaste/rustypaste ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "rustypaste" "orhun/rustypaste"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop rustypaste
|
||||
msg_ok "Stopped Services"
|
||||
|
||||
msg_info "Creating Backup"
|
||||
tar -czf "/opt/rustypaste_backup_$(date +%F).tar.gz" /opt/rustypaste/upload 2>/dev/null || true
|
||||
cp /opt/rustypaste/config.toml /tmp/rustypaste_config.toml.bak
|
||||
msg_ok "Backup Created"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "prebuild" "latest" "/opt/rustypaste" "*x86_64-unknown-linux-gnu.tar.gz"
|
||||
|
||||
msg_info "Restoring Data"
|
||||
mv /tmp/rustypaste_config.toml.bak /opt/rustypaste/config.toml
|
||||
tar -xzf "/opt/rustypaste_backup_$(date +%F).tar.gz" -C /opt/rustypaste/upload 2>/dev/null || true
|
||||
rm -rf /opt/rustypaste_backup_$(date +%F).tar.gz
|
||||
msg_ok "Restored Data"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start rustypaste
|
||||
msg_ok "Started Services"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "rustypaste-cli" "orhun/rustypaste-cli"; then
|
||||
fetch_and_deploy_gh_release "rustypaste-cli" "orhun/rustypaste-cli" "prebuild" "latest" "/usr/local/bin" "*x86_64-unknown-linux-gnu.tar.gz"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}rustypaste setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
||||
51
frontend/public/json/rustypaste.json
Normal file
51
frontend/public/json/rustypaste.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "RustyPaste",
|
||||
"slug": "rustypaste",
|
||||
"categories": [
|
||||
11
|
||||
],
|
||||
"date_created": "2025-12-22",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 8000,
|
||||
"documentation": "https://github.com/orhun/rustypaste",
|
||||
"config_path": "/opt/rustypaste/config.toml",
|
||||
"website": "https://github.com/orhun/rustypaste",
|
||||
"logo": "https://github.com/orhun/rustypaste/raw/master/img/rustypaste_logo.png",
|
||||
"description": "Rustypaste is a minimal file upload/pastebin service.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/rustypaste.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 1024,
|
||||
"hdd": 20,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alpine",
|
||||
"script": "ct/alpine-rustypaste.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 256,
|
||||
"hdd": 4,
|
||||
"os": "Alpine",
|
||||
"version": "3.23"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "When updating the script it will backup the whole project including all the uploaded files, make sure to extract it to a safe location or remove",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,320 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import type { Category } from "@/lib/types";
|
||||
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
const defaultLogo = "/default-logo.png"; // Fallback logo path
|
||||
const MAX_DESCRIPTION_LENGTH = 100; // Set max length for description
|
||||
const MAX_LOGOS = 5; // Max logos to display at once
|
||||
|
||||
function formattedBadge(type: string) {
|
||||
switch (type) {
|
||||
case "vm":
|
||||
return <Badge className="text-blue-500/75 border-blue-500/75 badge">VM</Badge>;
|
||||
case "ct":
|
||||
return <Badge className="text-yellow-500/75 border-yellow-500/75 badge">LXC</Badge>;
|
||||
case "pve":
|
||||
return <Badge className="text-orange-500/75 border-orange-500/75 badge">PVE</Badge>;
|
||||
case "addon":
|
||||
return <Badge className="text-green-500/75 border-green-500/75 badge">ADDON</Badge>;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function CategoryView() {
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
const [selectedCategoryIndex, setSelectedCategoryIndex] = useState<number | null>(null);
|
||||
const [currentScripts, setCurrentScripts] = useState<any[]>([]);
|
||||
const [logoIndices, setLogoIndices] = useState<{ [key: string]: number }>({});
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCategories = async () => {
|
||||
try {
|
||||
// eslint-disable-next-line node/no-process-env
|
||||
const basePath = process.env.NODE_ENV === "production" ? "/ProxmoxVE" : "";
|
||||
const response = await fetch(`${basePath}/api/categories`);
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch categories");
|
||||
}
|
||||
const data = await response.json();
|
||||
setCategories(data);
|
||||
|
||||
// Initialize logo indices
|
||||
const initialLogoIndices: { [key: string]: number } = {};
|
||||
data.forEach((category: any) => {
|
||||
initialLogoIndices[category.name] = 0;
|
||||
});
|
||||
setLogoIndices(initialLogoIndices);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error fetching categories:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCategories();
|
||||
}, []);
|
||||
|
||||
const handleCategoryClick = (index: number) => {
|
||||
setSelectedCategoryIndex(index);
|
||||
setCurrentScripts(categories[index]?.scripts || []); // Update scripts for the selected category
|
||||
};
|
||||
|
||||
const handleBackClick = () => {
|
||||
setSelectedCategoryIndex(null);
|
||||
setCurrentScripts([]); // Clear scripts when going back
|
||||
};
|
||||
|
||||
const handleScriptClick = (scriptSlug: string) => {
|
||||
// Include category context when navigating to scripts
|
||||
const categoryName = selectedCategoryIndex !== null ? categories[selectedCategoryIndex]?.name : null;
|
||||
const queryParams = new URLSearchParams({ id: scriptSlug });
|
||||
if (categoryName) {
|
||||
queryParams.append("category", categoryName);
|
||||
}
|
||||
router.push(`/scripts?${queryParams.toString()}`);
|
||||
};
|
||||
|
||||
const navigateCategory = (direction: "prev" | "next") => {
|
||||
if (selectedCategoryIndex !== null) {
|
||||
const newIndex
|
||||
= direction === "prev"
|
||||
? (selectedCategoryIndex - 1 + categories.length) % categories.length
|
||||
: (selectedCategoryIndex + 1) % categories.length;
|
||||
setSelectedCategoryIndex(newIndex);
|
||||
setCurrentScripts(categories[newIndex]?.scripts || []); // Update scripts for the new category
|
||||
}
|
||||
};
|
||||
|
||||
const switchLogos = (categoryName: string, direction: "prev" | "next") => {
|
||||
setLogoIndices((prev) => {
|
||||
const currentIndex = prev[categoryName] || 0;
|
||||
const category = categories.find(cat => cat.name === categoryName);
|
||||
if (!category || !category.scripts)
|
||||
return prev;
|
||||
|
||||
const totalLogos = category.scripts.length;
|
||||
const newIndex
|
||||
= direction === "prev"
|
||||
? (currentIndex - MAX_LOGOS + totalLogos) % totalLogos
|
||||
: (currentIndex + MAX_LOGOS) % totalLogos;
|
||||
|
||||
return { ...prev, [categoryName]: newIndex };
|
||||
});
|
||||
};
|
||||
|
||||
const truncateDescription = (text: string) => {
|
||||
return text.length > MAX_DESCRIPTION_LENGTH ? `${text.slice(0, MAX_DESCRIPTION_LENGTH)}...` : text;
|
||||
};
|
||||
|
||||
const renderResources = (script: any) => {
|
||||
const cpu = script.install_methods[0]?.resources.cpu;
|
||||
const ram = script.install_methods[0]?.resources.ram;
|
||||
const hdd = script.install_methods[0]?.resources.hdd;
|
||||
|
||||
const resourceParts = [];
|
||||
if (cpu) {
|
||||
resourceParts.push(
|
||||
<span key="cpu">
|
||||
<b>CPU:</b>
|
||||
{" "}
|
||||
{cpu}
|
||||
vCPU
|
||||
</span>,
|
||||
);
|
||||
}
|
||||
if (ram) {
|
||||
resourceParts.push(
|
||||
<span key="ram">
|
||||
<b>RAM:</b>
|
||||
{" "}
|
||||
{ram}
|
||||
MB
|
||||
</span>,
|
||||
);
|
||||
}
|
||||
if (hdd) {
|
||||
resourceParts.push(
|
||||
<span key="hdd">
|
||||
<b>HDD:</b>
|
||||
{" "}
|
||||
{hdd}
|
||||
GB
|
||||
</span>,
|
||||
);
|
||||
}
|
||||
|
||||
return resourceParts.length > 0
|
||||
? (
|
||||
<div className="text-sm text-gray-400">
|
||||
{resourceParts.map((part, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{part}
|
||||
{index < resourceParts.length - 1 && " | "}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-6 mt-20">
|
||||
{categories.length === 0 && (
|
||||
<p className="text-center text-gray-500">No categories available. Please check the API endpoint.</p>
|
||||
)}
|
||||
{selectedCategoryIndex !== null
|
||||
? (
|
||||
<div>
|
||||
{/* Header with Navigation */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => navigateCategory("prev")}
|
||||
className="p-2 transition-transform duration-300 hover:scale-105"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
</Button>
|
||||
<h2 className="text-3xl font-semibold transition-opacity duration-300 hover:opacity-90">
|
||||
{categories[selectedCategoryIndex].name}
|
||||
</h2>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => navigateCategory("next")}
|
||||
className="p-2 transition-transform duration-300 hover:scale-105"
|
||||
>
|
||||
<ChevronRight className="h-6 w-6" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Scripts Grid */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
||||
{currentScripts
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map(script => (
|
||||
<Card
|
||||
key={script.name}
|
||||
className="p-4 cursor-pointer hover:shadow-md transition-shadow duration-300"
|
||||
onClick={() => handleScriptClick(script.slug)}
|
||||
>
|
||||
<CardContent className="flex flex-col gap-4">
|
||||
<h3 className="text-lg font-bold script-text text-center hover:text-blue-600 transition-colors duration-300">
|
||||
{script.name}
|
||||
</h3>
|
||||
<img
|
||||
src={script.logo || defaultLogo}
|
||||
alt={script.name || "Script logo"}
|
||||
className="h-12 w-12 object-contain mx-auto"
|
||||
/>
|
||||
<p className="text-sm text-gray-500 text-center">
|
||||
<b>Created at:</b>
|
||||
{" "}
|
||||
{script.date_created || "No date available"}
|
||||
</p>
|
||||
<p
|
||||
className="text-sm text-gray-700 hover:text-gray-900 text-center transition-colors duration-300"
|
||||
title={script.description || "No description available."}
|
||||
>
|
||||
{truncateDescription(script.description || "No description available.")}
|
||||
</p>
|
||||
{renderResources(script)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Back to Categories Button */}
|
||||
<div className="mt-8 text-center">
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={handleBackClick}
|
||||
className="px-6 py-2 text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow-md transition-transform duration-300 hover:scale-105"
|
||||
>
|
||||
Back to Categories
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<div>
|
||||
{/* Categories Grid */}
|
||||
<div className="flex justify-between items-center mb-8">
|
||||
<h1 className="text-3xl font-semibold mb-4">Categories</h1>
|
||||
<p className="text-sm text-gray-500">
|
||||
{categories.reduce((total, category) => total + (category.scripts?.length || 0), 0)}
|
||||
{" "}
|
||||
Total scripts
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
|
||||
{categories.map((category, index) => (
|
||||
<Card
|
||||
key={category.name}
|
||||
onClick={() => handleCategoryClick(index)}
|
||||
className="cursor-pointer hover:shadow-lg flex flex-col items-center justify-center py-6 transition-shadow duration-300"
|
||||
>
|
||||
<CardContent className="flex flex-col items-center">
|
||||
<h3 className="text-xl font-bold mb-4 category-title transition-colors duration-300 hover:text-blue-600">
|
||||
{category.name}
|
||||
</h3>
|
||||
<div className="flex justify-center items-center gap-2 mb-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
switchLogos(category.name, "prev");
|
||||
}}
|
||||
className="p-1 transition-transform duration-300 hover:scale-110"
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
</Button>
|
||||
{category.scripts
|
||||
&& category.scripts
|
||||
.slice(logoIndices[category.name] || 0, (logoIndices[category.name] || 0) + MAX_LOGOS)
|
||||
.map((script, i) => (
|
||||
<div key={i} className="flex flex-col items-center">
|
||||
<img
|
||||
src={script.logo || defaultLogo}
|
||||
alt={script.name || "Script logo"}
|
||||
title={script.name}
|
||||
className="h-8 w-8 object-contain cursor-pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleScriptClick(script.slug);
|
||||
}}
|
||||
/>
|
||||
{formattedBadge(script.type)}
|
||||
</div>
|
||||
))}
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
switchLogos(category.name, "next");
|
||||
}}
|
||||
className="p-1 transition-transform duration-300 hover:scale-110"
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-sm text-gray-400 text-center">
|
||||
{(category as any).description || "No description available."}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CategoryView;
|
||||
55
install/alpine-rustypaste-install.sh
Normal file
55
install/alpine-rustypaste-install.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/orhun/rustypaste
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing RustyPaste"
|
||||
$STD apk add --no-cache rustypaste --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
|
||||
msg_ok "Installed RustyPaste"
|
||||
|
||||
msg_info "Configuring RustyPaste"
|
||||
mkdir -p /var/lib/rustypaste
|
||||
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' /etc/rustypaste/config.toml
|
||||
msg_ok "Configured RustyPaste"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<'EOF' >/etc/init.d/rustypaste
|
||||
#!/sbin/openrc-run
|
||||
|
||||
name="rustypaste"
|
||||
description="RustyPaste - A minimal file upload/pastebin service"
|
||||
command="/usr/bin/rustypaste"
|
||||
command_args=""
|
||||
command_user="root"
|
||||
command_background=true
|
||||
pidfile="/run/${RC_SVCNAME}.pid"
|
||||
directory="/var/lib/rustypaste"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
after firewall
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
export CONFIG=/etc/rustypaste/config.toml
|
||||
checkpath --directory --owner root:root --mode 0755 /var/lib/rustypaste
|
||||
}
|
||||
EOF
|
||||
chmod +x /etc/init.d/rustypaste
|
||||
$STD rc-update add rustypaste default
|
||||
$STD rc-service rustypaste start
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
43
install/rustypaste-install.sh
Normal file
43
install/rustypaste-install.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: GoldenSpringness | MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/orhun/rustypaste
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "prebuild" "latest" "/opt/rustypaste" "*x86_64-unknown-linux-gnu.tar.gz"
|
||||
fetch_and_deploy_gh_release "rustypaste-cli" "orhun/rustypaste-cli" "prebuild" "latest" "/usr/local/bin" "*x86_64-unknown-linux-gnu.tar.gz"
|
||||
|
||||
msg_info "Setting up RustyPaste"
|
||||
cd /opt/rustypaste
|
||||
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' config.toml
|
||||
msg_ok "Set up RustyPaste"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/rustypaste.service
|
||||
[Unit]
|
||||
Description=rustypaste Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/rustypaste
|
||||
ExecStart=/opt/rustypaste/rustypaste
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now rustypaste
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
Reference in New Issue
Block a user