mirror of
https://github.com/community-scripts/ProxmoxVE
synced 2025-02-14 11:49:16 +00:00
Compare commits
16 Commits
347889f0d4
...
1088d96561
Author | SHA1 | Date | |
---|---|---|---|
|
1088d96561 | ||
|
7f2481ea12 | ||
|
05f114ed64 | ||
|
6924a6fea4 | ||
|
bb553ae48c | ||
|
cbb18668dd | ||
|
c7418171b4 | ||
|
ed2ead9ef2 | ||
|
e51c121af2 | ||
|
8c4e97d6cb | ||
|
1093fef23c | ||
|
6fa540f0da | ||
|
ca7fb9b929 | ||
|
139f84a934 | ||
|
8bc50f4d71 | ||
|
3fa4cf6e07 |
12
CHANGELOG.md
12
CHANGELOG.md
@ -17,20 +17,32 @@ All LXC instances created using this repository come pre-installed with Midnight
|
||||
Do not break established syntax in this file, as it is automatically updated by a Github Workflow
|
||||
|
||||
|
||||
## 2025-01-30
|
||||
|
||||
### Changed
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- fix: remove rounded styles from command primitive [@steveiliop56](https://github.com/steveiliop56) ([#1840](https://github.com/community-scripts/ProxmoxVE/pull/1840))
|
||||
|
||||
## 2025-01-29
|
||||
|
||||
### Changed
|
||||
|
||||
### ✨ New Scripts
|
||||
|
||||
- New Script: Prometheus Proxmox VE Exporter [@andygrunwald](https://github.com/andygrunwald) ([#1805](https://github.com/community-scripts/ProxmoxVE/pull/1805))
|
||||
- New Script: Clean Orphaned LVM [@MickLesk](https://github.com/MickLesk) ([#1838](https://github.com/community-scripts/ProxmoxVE/pull/1838))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- Patch http Url to https in build.func and /data/page.tsx [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1849](https://github.com/community-scripts/ProxmoxVE/pull/1849))
|
||||
- [Frontend] Add /data to show API results [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1841](https://github.com/community-scripts/ProxmoxVE/pull/1841))
|
||||
- Update clean-orphaned-lvm.json [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1843](https://github.com/community-scripts/ProxmoxVE/pull/1843))
|
||||
|
||||
### 🧰 Maintenance
|
||||
|
||||
- Update build.func [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1851](https://github.com/community-scripts/ProxmoxVE/pull/1851))
|
||||
- [Diagnostic] Introduced optional lxc install diagnostics via API call [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#1801](https://github.com/community-scripts/ProxmoxVE/pull/1801))
|
||||
|
||||
## 2025-01-28
|
||||
|
62
ct/alpine-it-tools.sh
Normal file
62
ct/alpine-it-tools.sh
Normal file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: nicedevil007 (NiceDevil)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
|
||||
# App Default Values
|
||||
APP="Alpine-IT-Tools"
|
||||
var_tags="alpine;development"
|
||||
var_cpu="1"
|
||||
var_ram="256"
|
||||
var_disk="0.2"
|
||||
var_os="alpine"
|
||||
var_version="3.21"
|
||||
var_unprivileged="1"
|
||||
|
||||
# App Output & Base Settings
|
||||
header_info "$APP"
|
||||
base_settings
|
||||
|
||||
# Core
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /usr/share/nginx/html ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
RELEASE=$(curl -s https://api.github.com/repos/CorentinTh/it-tools/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
|
||||
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||
DOWNLOAD_URL="https://github.com/CorentinTh/it-tools/releases/download/${RELEASE}/it-tools-${RELEASE#v}.zip"
|
||||
msg_info "Updating ${APP} LXC"
|
||||
curl -fsSL -o it-tools.zip "$DOWNLOAD_URL"
|
||||
mkdir -p /usr/share/nginx/html
|
||||
rm -rf /usr/share/nginx/html/*
|
||||
unzip -q it-tools.zip -d /tmp/it-tools
|
||||
cp -r /tmp/it-tools/dist/* /usr/share/nginx/html
|
||||
rm -rf /tmp/it-tools
|
||||
rm -f it-tools.zip
|
||||
msg_ok "Updated Successfully"
|
||||
else
|
||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
||||
fi
|
||||
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 IP:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
6
ct/headers/alpine-it-tools
Normal file
6
ct/headers/alpine-it-tools
Normal file
@ -0,0 +1,6 @@
|
||||
___ __ _ __________ ______ __
|
||||
/ | / /___ (_)___ ___ / _/_ __/ /_ __/___ ____ / /____
|
||||
/ /| | / / __ \/ / __ \/ _ \______ / / / /_____/ / / __ \/ __ \/ / ___/
|
||||
/ ___ |/ / /_/ / / / / / __/_____// / / /_____/ / / /_/ / /_/ / (__ )
|
||||
/_/ |_/_/ .___/_/_/ /_/\___/ /___/ /_/ /_/ \____/\____/_/____/
|
||||
/_/
|
6
ct/headers/mattermost
Normal file
6
ct/headers/mattermost
Normal file
@ -0,0 +1,6 @@
|
||||
__ ___ __ __ __
|
||||
/ |/ /___ _/ /_/ /____ _________ ___ ____ _____/ /_
|
||||
/ /|_/ / __ `/ __/ __/ _ \/ ___/ __ `__ \/ __ \/ ___/ __/
|
||||
/ / / / /_/ / /_/ /_/ __/ / / / / / / / /_/ (__ ) /_
|
||||
/_/ /_/\__,_/\__/\__/\___/_/ /_/ /_/ /_/\____/____/\__/
|
||||
|
12
ct/headers/prometheus-pve-exporter
Normal file
12
ct/headers/prometheus-pve-exporter
Normal file
@ -0,0 +1,12 @@
|
||||
____ __ __ ____
|
||||
/ __ \_________ ____ ___ ___ / /_/ /_ ___ __ _______ / __ \
|
||||
/ /_/ / ___/ __ \/ __ `__ \/ _ \/ __/ __ \/ _ \/ / / / ___/_____/ /_/ /
|
||||
/ ____/ / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ )_____/ ____/
|
||||
/_/ /_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ /_/
|
||||
|
||||
_ ________ ______ __
|
||||
| | / / ____/ / ____/ ______ ____ _____/ /____ _____
|
||||
| | / / __/______/ __/ | |/_/ __ \/ __ \/ ___/ __/ _ \/ ___/
|
||||
| |/ / /__/_____/ /____> </ /_/ / /_/ / / / /_/ __/ /
|
||||
|___/_____/ /_____/_/|_/ .___/\____/_/ \__/\___/_/
|
||||
/_/
|
49
ct/mattermost.sh
Normal file
49
ct/mattermost.sh
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: Kaedon Cleland-Host (dracentis)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://mattermost.com/
|
||||
|
||||
# App Default Values
|
||||
APP="Mattermost"
|
||||
var_tags="collaboration"
|
||||
var_cpu="1"
|
||||
var_ram="2048"
|
||||
var_disk="8"
|
||||
var_os="ubuntu"
|
||||
var_version="24.04"
|
||||
var_unprivileged="1"
|
||||
|
||||
# App Output & Base Settings
|
||||
header_info "$APP"
|
||||
base_settings
|
||||
|
||||
# Core
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -f /etc/apt/sources.list.d/mattermost.list ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_info "Updating ${APP} LXC"
|
||||
apt-get update &>/dev/null
|
||||
apt-get -y upgrade &>/dev/null
|
||||
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}:8065${CL}"
|
53
frontend/package-lock.json
generated
53
frontend/package-lock.json
generated
@ -38,6 +38,7 @@
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"react": "19.0.0-rc-02c0e824-20241028",
|
||||
"react-code-blocks": "^0.1.6",
|
||||
"react-datepicker": "^7.6.0",
|
||||
"react-day-picker": "8.10.1",
|
||||
"react-dom": "19.0.0-rc-02c0e824-20241028",
|
||||
"react-icons": "^5.1.0",
|
||||
@ -1083,9 +1084,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
|
||||
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
@ -8017,6 +8018,46 @@
|
||||
"react": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.6.0.tgz",
|
||||
"integrity": "sha512-9cQH6Z/qa4LrGhzdc3XoHbhrxNcMi9MKjZmYgF/1MNNaJwvdSjv3Xd+jjvrEEbKEf71ZgCA3n7fQbdwd70qCRw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.27.0",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^3.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc",
|
||||
"react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker/node_modules/@floating-ui/react": {
|
||||
"version": "0.27.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.3.tgz",
|
||||
"integrity": "sha512-CLHnes3ixIFFKVQDdICjel8muhFLOBdQH7fgtHNPY8UbCNqbeKZ262G7K66lGQOUQWWnYocf7ZbUsLJgGfsLHg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.1.2",
|
||||
"@floating-ui/utils": "^0.2.9",
|
||||
"tabbable": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0.0",
|
||||
"react-dom": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker/node_modules/date-fns": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
|
||||
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/react-day-picker": {
|
||||
"version": "8.10.1",
|
||||
"resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz",
|
||||
@ -9055,6 +9096,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tabbable": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
|
||||
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "2.5.4",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz",
|
||||
|
@ -49,6 +49,7 @@
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"react": "19.0.0-rc-02c0e824-20241028",
|
||||
"react-code-blocks": "^0.1.6",
|
||||
"react-datepicker": "^7.6.0",
|
||||
"react-day-picker": "8.10.1",
|
||||
"react-dom": "19.0.0-rc-02c0e824-20241028",
|
||||
"react-icons": "^5.1.0",
|
||||
|
236
frontend/src/app/data/page.tsx
Normal file
236
frontend/src/app/data/page.tsx
Normal file
@ -0,0 +1,236 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import DatePicker from 'react-datepicker';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
import { string } from "zod";
|
||||
|
||||
|
||||
interface DataModel {
|
||||
id: number;
|
||||
ct_type: number;
|
||||
disk_size: number;
|
||||
core_count: number;
|
||||
ram_size: number;
|
||||
verbose: string;
|
||||
os_type: string;
|
||||
os_version: string;
|
||||
hn: string;
|
||||
disableip6: string;
|
||||
ssh: string;
|
||||
tags: string;
|
||||
nsapp: string;
|
||||
created_at: string;
|
||||
method: string;
|
||||
pve_version: string;
|
||||
}
|
||||
|
||||
|
||||
const DataFetcher: React.FC = () => {
|
||||
const [data, setData] = useState<DataModel[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [startDate, setStartDate] = useState<Date | null>(null);
|
||||
const [endDate, setEndDate] = useState<Date | null>(null);
|
||||
const [sortConfig, setSortConfig] = useState<{ key: keyof DataModel | null, direction: 'ascending' | 'descending' }>({ key: 'id', direction: 'descending' });
|
||||
const [itemsPerPage, setItemsPerPage] = useState(5);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await fetch("https://api.htl-braunau.at/data/json");
|
||||
if (!response.ok) throw new Error("Failed to fetch data: ${response.statusText}");
|
||||
const result: DataModel[] = await response.json();
|
||||
setData(result);
|
||||
} catch (err) {
|
||||
setError((err as Error).message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
|
||||
const filteredData = data.filter(item => {
|
||||
const matchesSearchQuery = Object.values(item).some(value =>
|
||||
value.toString().toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
const itemDate = new Date(item.created_at);
|
||||
const matchesDateRange = (!startDate || itemDate >= startDate) && (!endDate || itemDate <= endDate);
|
||||
return matchesSearchQuery && matchesDateRange;
|
||||
});
|
||||
|
||||
const sortedData = React.useMemo(() => {
|
||||
let sortableData = [...filteredData];
|
||||
if (sortConfig.key !== null) {
|
||||
sortableData.sort((a, b) => {
|
||||
if (sortConfig.key !== null && a[sortConfig.key] < b[sortConfig.key]) {
|
||||
return sortConfig.direction === 'ascending' ? -1 : 1;
|
||||
}
|
||||
if (sortConfig.key !== null && a[sortConfig.key] > b[sortConfig.key]) {
|
||||
return sortConfig.direction === 'ascending' ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return sortableData;
|
||||
}, [filteredData, sortConfig]);
|
||||
|
||||
const requestSort = (key: keyof DataModel | null) => {
|
||||
let direction: 'ascending' | 'descending' = 'ascending';
|
||||
if (sortConfig.key === key && sortConfig.direction === 'ascending') {
|
||||
direction = 'descending';
|
||||
} else if (sortConfig.key === key && sortConfig.direction === 'descending') {
|
||||
direction = 'ascending';
|
||||
} else {
|
||||
direction = 'descending';
|
||||
}
|
||||
setSortConfig({ key, direction });
|
||||
};
|
||||
|
||||
interface SortConfig {
|
||||
key: keyof DataModel | null;
|
||||
direction: 'ascending' | 'descending';
|
||||
}
|
||||
|
||||
const formatDate = (dateString: string): string => {
|
||||
const date = new Date(dateString);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const timezoneOffset = dateString.slice(-6);
|
||||
return `${day}.${month}.${year} ${hours}:${minutes} ${timezoneOffset} GMT`;
|
||||
};
|
||||
|
||||
const handleItemsPerPageChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setItemsPerPage(Number(event.target.value));
|
||||
setCurrentPage(1);
|
||||
};
|
||||
|
||||
const paginatedData = sortedData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);
|
||||
|
||||
if (loading) return <p>Loading...</p>;
|
||||
if (error) return <p>Error: {error}</p>;
|
||||
|
||||
|
||||
return (
|
||||
<div className="p-6 mt-20">
|
||||
<h1 className="text-2xl font-bold mb-4 text-center">Created LXCs</h1>
|
||||
<div className="mb-4 flex space-x-4">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
value={searchQuery}
|
||||
onChange={e => setSearchQuery(e.target.value)}
|
||||
className="p-2 border"
|
||||
/>
|
||||
<label className="text-sm text-gray-600 mt-1 block">Search by keyword</label>
|
||||
</div>
|
||||
<div>
|
||||
<DatePicker
|
||||
selected={startDate}
|
||||
onChange={date => setStartDate(date)}
|
||||
selectsStart
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
placeholderText="Start date"
|
||||
className="p-2 border"
|
||||
/>
|
||||
<label className="text-sm text-gray-600 mt-1 block">Set a start date</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<DatePicker
|
||||
selected={endDate}
|
||||
onChange={date => setEndDate(date)}
|
||||
selectsEnd
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
placeholderText="End date"
|
||||
className="p-2 border"
|
||||
/>
|
||||
<label className="text-sm text-gray-600 mt-1 block">Set a end date</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4 flex justify-between items-center">
|
||||
<p className="text-lg font-bold">{filteredData.length} results found</p>
|
||||
<select value={itemsPerPage} onChange={handleItemsPerPageChange} className="p-2 border">
|
||||
<option value={5}>5</option>
|
||||
<option value={10}>10</option>
|
||||
<option value={20}>20</option>
|
||||
<option value={50}>50</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<div className="overflow-y-auto lg:overflow-y-visible">
|
||||
<table className="min-w-full table-auto border-collapse">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('nsapp')}>Application</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('os_type')}>OS</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('os_version')}>OS Version</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('disk_size')}>Disk Size</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('core_count')}>Core Count</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('ram_size')}>RAM Size</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('hn')}>Hostname</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('ssh')}>SSH</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('verbose')}>Verb</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('tags')}>Tags</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('method')}>Method</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('pve_version')}>PVE Version</th>
|
||||
<th className="px-4 py-2 border-b cursor-pointer" onClick={() => requestSort('created_at')}>Created At</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{paginatedData.map((item, index) => (
|
||||
<tr key={index}>
|
||||
<td className="px-4 py-2 border-b">{item.nsapp}</td>
|
||||
<td className="px-4 py-2 border-b">{item.os_type}</td>
|
||||
<td className="px-4 py-2 border-b">{item.os_version}</td>
|
||||
<td className="px-4 py-2 border-b">{item.disk_size}</td>
|
||||
<td className="px-4 py-2 border-b">{item.core_count}</td>
|
||||
<td className="px-4 py-2 border-b">{item.ram_size}</td>
|
||||
<td className="px-4 py-2 border-b">{item.hn}</td>
|
||||
<td className="px-4 py-2 border-b">{item.ssh}</td>
|
||||
<td className="px-4 py-2 border-b">{item.verbose}</td>
|
||||
<td className="px-4 py-2 border-b">{item.tags.replace(/;/g, ' ')}</td>
|
||||
<td className="px-4 py-2 border-b">{item.method}</td>
|
||||
<td className="px-4 py-2 border-b">{item.pve_version}</td>
|
||||
<td className="px-4 py-2 border-b">{formatDate(item.created_at)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex justify-between items-center">
|
||||
<button
|
||||
onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
|
||||
disabled={currentPage === 1}
|
||||
className="p-2 border"
|
||||
>
|
||||
Previous
|
||||
</button>
|
||||
<span>Page {currentPage}</span>
|
||||
<button
|
||||
onClick={() => setCurrentPage(prev => (prev * itemsPerPage < sortedData.length ? prev + 1 : prev))}
|
||||
disabled={currentPage * itemsPerPage >= sortedData.length}
|
||||
className="p-2 border"
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default DataFetcher;
|
@ -15,7 +15,7 @@ const Command = React.forwardRef<
|
||||
<CommandPrimitive
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
||||
"flex h-full w-full flex-col overflow-hidden bg-popover text-popover-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
56
install/alpine-it-tools-install.sh
Normal file
56
install/alpine-it-tools-install.sh
Normal file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: nicedevil007 (NiceDevil)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
|
||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apk add \
|
||||
curl \
|
||||
mc \
|
||||
nginx \
|
||||
unzip
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Installing IT-Tools"
|
||||
RELEASE=$(curl -s https://api.github.com/repos/CorentinTh/it-tools/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
|
||||
DOWNLOAD_URL="https://github.com/CorentinTh/it-tools/releases/download/${RELEASE}/it-tools-${RELEASE#v}.zip"
|
||||
|
||||
curl -fsSL -o it-tools.zip "$DOWNLOAD_URL"
|
||||
mkdir -p /usr/share/nginx/html
|
||||
unzip -q it-tools.zip -d /tmp/it-tools
|
||||
cp -r /tmp/it-tools/dist/* /usr/share/nginx/html
|
||||
cat <<'EOF' > /etc/nginx/http.d/default.conf
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
$STD rc-update add nginx default
|
||||
$STD rc-service nginx start
|
||||
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
|
||||
msg_ok "Installed IT-Tools"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Cleaning up"
|
||||
rm -rf /tmp/it-tools
|
||||
rm -f it-tools.zip
|
||||
$STD apk cache clean
|
||||
msg_ok "Cleaned"
|
60
install/mattermost-install.sh
Normal file
60
install/mattermost-install.sh
Normal file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: Kaedon Cleland-Host (dracentis)
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y \
|
||||
curl \
|
||||
sudo \
|
||||
mc \
|
||||
gpg \
|
||||
postgresql
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Setting up PostgreSQL"
|
||||
DB_NAME=mattermost
|
||||
DB_USER=mmuser
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;"
|
||||
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
|
||||
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;"
|
||||
$STD sudo -u postgres psql -c "ALTER DATABASE $DB_NAME OWNER TO $DB_USER;"
|
||||
$STD sudo -u postgres psql -c "GRANT USAGE, CREATE ON SCHEMA PUBLIC TO $DB_USER;"
|
||||
{
|
||||
echo "Mattermost Credentials"
|
||||
echo "Database User: $DB_USER"
|
||||
echo "Database Password: $DB_PASS"
|
||||
echo "Database Name: $DB_NAME"
|
||||
} >> ~/mattermost.creds
|
||||
msg_ok "Set up PostgreSQL"
|
||||
|
||||
msg_info "Installing Mattermost"
|
||||
IPADDRESS=$(hostname -I | awk '{print $1}')
|
||||
curl -sL -o- /usr/share/keyrings/mattermost-archive-keyring.gpg https://deb.packages.mattermost.com/pubkey.gpg
|
||||
sh -c 'curl -o- https://deb.packages.mattermost.com/repo-setup.sh | sudo bash -s mattermost'
|
||||
$STD apt-get update
|
||||
$STD apt-get install -y mattermost
|
||||
$STD install -C -m 600 -o mattermost -g mattermost /opt/mattermost/config/config.defaults.json /opt/mattermost/config/config.json
|
||||
sed -i -e "/DataSource/c\ \"DataSource\": \"postgres://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?sslmode=disable&connect_timeout=10\"," \
|
||||
-e "/SiteURL/c\ \"SiteURL\": \"http://$IPADDRESS:8065\"," /opt/mattermost/config/config.json
|
||||
systemctl enable -q --now mattermost.service
|
||||
msg_ok "Installed Mattermost"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Cleaning up"
|
||||
$STD apt-get -y autoremove
|
||||
$STD apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
34
json/it-tools.json
Normal file
34
json/it-tools.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "IT-Tools",
|
||||
"slug": "it-tools",
|
||||
"categories": [
|
||||
20
|
||||
],
|
||||
"date_created": "2025-01-30",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 80,
|
||||
"documentation": null,
|
||||
"website": "https://it-tools.tech/",
|
||||
"logo": "https://raw.githubusercontent.com/CorentinTh/it-tools/08d977b8cdb7ffb76adfa18ba6eb4b73795ec814/public/safari-pinned-tab.svg",
|
||||
"description": "IT-Tools is a web-based suite of utilities designed to streamline and simplify various IT tasks, providing tools for developers and system administrators to manage their workflows efficiently.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/alpine-it-tools.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 256,
|
||||
"hdd": 0.2,
|
||||
"os": "alpine",
|
||||
"version": "3.21"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
34
json/mattermost.json
Normal file
34
json/mattermost.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "Mattermost",
|
||||
"slug": "mattermost",
|
||||
"categories": [
|
||||
25
|
||||
],
|
||||
"date_created": "2025-01-30",
|
||||
"type": "ct",
|
||||
"updateable": false,
|
||||
"privileged": false,
|
||||
"interface_port": 8065,
|
||||
"documentation": null,
|
||||
"website": "https://mattermost.com/",
|
||||
"logo": "https://avatars.githubusercontent.com/u/9828093?s=200&v=4",
|
||||
"description": "Mattermost is an open source platform for secure collaboration across the entire software development lifecycle. It's written in Go and React and runs as a single Linux binary with MySQL or PostgreSQL. It has a slimilar interface and features to Slack or Discord.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/mattermost.sh",
|
||||
"resources": {
|
||||
"cpu": 1,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "ubuntu",
|
||||
"version": "24.04"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
@ -102,7 +102,7 @@ while true; do
|
||||
esac
|
||||
done
|
||||
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[0-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[0-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
msg_error "⚠️ Requires Proxmox Virtual Environment Version 8.0 or later."
|
||||
msg_error "Exiting..."
|
||||
|
@ -140,7 +140,7 @@ root_check() {
|
||||
|
||||
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
||||
pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -231,7 +231,7 @@ while true; do
|
||||
esac
|
||||
done
|
||||
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[0-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[0-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.0 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -111,7 +111,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -111,7 +111,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -91,7 +91,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -115,7 +115,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -62,7 +62,7 @@ function cleanup() {
|
||||
}
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
pushd $TEMP_DIR >/dev/null
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -91,7 +91,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -157,7 +157,7 @@ function msg_error() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -91,7 +91,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -111,7 +111,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -112,7 +112,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
@ -111,7 +111,7 @@ function check_root() {
|
||||
}
|
||||
|
||||
function pve_check() {
|
||||
if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
|
||||
if ! pveversion | grep -Eq "pve-manager/8\.[1-3](\.[0-9]+)*"; then
|
||||
msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
|
||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
|
||||
echo -e "Exiting..."
|
||||
|
Loading…
Reference in New Issue
Block a user