mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-11-04 18:32:51 +00:00
Compare commits
28 Commits
2025-02-13
...
2025-02-16
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a646a035d8 | ||
|
|
505cb23467 | ||
|
|
345e109d9f | ||
|
|
bca944034a | ||
|
|
be27905776 | ||
|
|
53196c7603 | ||
|
|
0777ddfbfc | ||
|
|
18bd71da89 | ||
|
|
ecd13dd5a4 | ||
|
|
3ef1ac434a | ||
|
|
60e32a05cd | ||
|
|
b7df0ee936 | ||
|
|
4cf24c54d7 | ||
|
|
c4ed0738cf | ||
|
|
88b20e5545 | ||
|
|
7c5b072303 | ||
|
|
347a23ad60 | ||
|
|
29806c4525 | ||
|
|
a045dc8012 | ||
|
|
80e7e2f5b6 | ||
|
|
1789d181aa | ||
|
|
f0ca0c3379 | ||
|
|
1711e44a4d | ||
|
|
afe4af2ff6 | ||
|
|
ec8c564e25 | ||
|
|
fd9d64b342 | ||
|
|
1d928f7ea8 | ||
|
|
f3c9e8f013 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: "🐞 Script Issue Report"
|
name: "🐞 Script Issue Report"
|
||||||
description: Report a specific issue with a script. For other inquiries, please use the Discussions section.
|
description: Report a specific issue with a script. For other inquiries, please use the Discussions section.
|
||||||
|
labels: ["bug"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -3,7 +3,7 @@ contact_links:
|
|||||||
- name: 🤔 Questions and Help
|
- name: 🤔 Questions and Help
|
||||||
url: https://github.com/community-scripts/ProxmoxVE/discussions
|
url: https://github.com/community-scripts/ProxmoxVE/discussions
|
||||||
about: For suggestions or questions, please use the Discussions section.
|
about: For suggestions or questions, please use the Discussions section.
|
||||||
- name: 🌟 Feature request
|
- name: 🌟 new Script request
|
||||||
url: https://github.com/community-scripts/ProxmoxVE/discussions/new?category=request-script
|
url: https://github.com/community-scripts/ProxmoxVE/discussions/new?category=request-script
|
||||||
about: For feature/script requests, please use the Discussions section.
|
about: For feature/script requests, please use the Discussions section.
|
||||||
- name: 💻 Discord
|
- name: 💻 Discord
|
||||||
|
|||||||
33
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
33
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: "✨ Feature Request"
|
||||||
|
description: "Suggest a new feature or enhancement."
|
||||||
|
labels: ["enhancement"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
# ✨ **Feature Request**
|
||||||
|
Have an idea for a new feature? Share your thoughts below!
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: feature_summary
|
||||||
|
attributes:
|
||||||
|
label: "🌟 Briefly describe the feature"
|
||||||
|
placeholder: "e.g., Add support for XYZ"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: feature_description
|
||||||
|
attributes:
|
||||||
|
label: "📝 Detailed description"
|
||||||
|
placeholder: "Explain the feature in detail"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: use_case
|
||||||
|
attributes:
|
||||||
|
label: "💡 Why is this useful?"
|
||||||
|
placeholder: "Describe the benefit of this feature"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
25
.github/ISSUE_TEMPLATE/task.yml
vendored
Normal file
25
.github/ISSUE_TEMPLATE/task.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: "🛠️ Task / General Request"
|
||||||
|
description: "Request a general task, improvement, or refactor."
|
||||||
|
labels: ["task"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
# 🛠️ **Task / General Request**
|
||||||
|
Request a task that isn't a bug or feature request.
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: task_summary
|
||||||
|
attributes:
|
||||||
|
label: "📌 Task summary"
|
||||||
|
placeholder: "e.g., Refactor XYZ"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: task_details
|
||||||
|
attributes:
|
||||||
|
label: "📋 Task details"
|
||||||
|
placeholder: "Explain what needs to be done"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
14
.github/workflows/script-test.yml
vendored
14
.github/workflows/script-test.yml
vendored
@@ -89,10 +89,16 @@ jobs:
|
|||||||
chmod +x "$INSTALL_SCRIPT"
|
chmod +x "$INSTALL_SCRIPT"
|
||||||
RUNNING_FILE=$FILE
|
RUNNING_FILE=$FILE
|
||||||
fi
|
fi
|
||||||
git checkout origin/main .github/workflows/scripts/app-test/pr-build.func
|
git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
|
||||||
git checkout origin/main .github/workflows/scripts/app-test/pr-install.func
|
git fetch community-scripts
|
||||||
git checkout origin/main .github/workflows/scripts/app-test/pr-alpine-install.func
|
rm -f .github/workflows/scripts/app-test/pr-build.func || true
|
||||||
git checkout origin/main .github/workflows/scripts/app-test/pr-create-lxc.sh
|
rm -f .github/workflows/scripts/app-test/pr-install.func || true
|
||||||
|
rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
|
||||||
|
rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
|
||||||
|
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
|
||||||
|
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
|
||||||
|
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
|
||||||
|
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
|
||||||
chmod +x $RUNNING_FILE
|
chmod +x $RUNNING_FILE
|
||||||
chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
|
chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
|
||||||
chmod +x .github/workflows/scripts/app-test/pr-install.func
|
chmod +x .github/workflows/scripts/app-test/pr-install.func
|
||||||
|
|||||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -17,6 +17,60 @@ 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
|
Do not break established syntax in this file, as it is automatically updated by a Github Workflow
|
||||||
|
|
||||||
|
|
||||||
|
## 2025-02-16
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Fix: Typo in Ubuntu 24.10 VM Script [@PhoenixEmik](https://github.com/PhoenixEmik) ([#2430](https://github.com/community-scripts/ProxmoxVE/pull/2430))
|
||||||
|
- Fix: Grist update no longer removes previous user data [@cfurrow](https://github.com/cfurrow) ([#2428](https://github.com/community-scripts/ProxmoxVE/pull/2428))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- Debian icon update [@bannert1337](https://github.com/bannert1337) ([#2433](https://github.com/community-scripts/ProxmoxVE/pull/2433))
|
||||||
|
- Update Graylog icon [@bannert1337](https://github.com/bannert1337) ([#2434](https://github.com/community-scripts/ProxmoxVE/pull/2434))
|
||||||
|
|
||||||
|
## 2025-02-15
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Setup cron in install/freshrss-install.sh [@zimmra](https://github.com/zimmra) ([#2412](https://github.com/community-scripts/ProxmoxVE/pull/2412))
|
||||||
|
- Fix: Homarr update service files [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2416](https://github.com/community-scripts/ProxmoxVE/pull/2416))
|
||||||
|
- Update MagicMirror install and update scripts [@tremor021](https://github.com/tremor021) ([#2409](https://github.com/community-scripts/ProxmoxVE/pull/2409))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- Fix RustDesk slug in json [@tremor021](https://github.com/tremor021) ([#2411](https://github.com/community-scripts/ProxmoxVE/pull/2411))
|
||||||
|
|
||||||
|
### 🧰 Maintenance
|
||||||
|
|
||||||
|
- [GH] Update script-test Workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2415](https://github.com/community-scripts/ProxmoxVE/pull/2415))
|
||||||
|
|
||||||
|
## 2025-02-14
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Fix homarr [@CrazyWolf13](https://github.com/CrazyWolf13) ([#2369](https://github.com/community-scripts/ProxmoxVE/pull/2369))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- RustDesk Server - Added configuration guide to json [@tremor021](https://github.com/tremor021) ([#2389](https://github.com/community-scripts/ProxmoxVE/pull/2389))
|
||||||
|
|
||||||
|
### 🧰 Maintenance
|
||||||
|
|
||||||
|
- [gh] Update script-test.yml [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2399](https://github.com/community-scripts/ProxmoxVE/pull/2399))
|
||||||
|
- [gh] Introducing new Issue Github Template Feature (Bug, Feature, Task) [@MickLesk](https://github.com/MickLesk) ([#2394](https://github.com/community-scripts/ProxmoxVE/pull/2394))
|
||||||
|
|
||||||
|
### 📡 API
|
||||||
|
|
||||||
|
- [API]Add more enpoints to API [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2390](https://github.com/community-scripts/ProxmoxVE/pull/2390))
|
||||||
|
- [API] Update api.func: Remove unwanted file creation [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#2378](https://github.com/community-scripts/ProxmoxVE/pull/2378))
|
||||||
|
|
||||||
## 2025-02-13
|
## 2025-02-13
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
283
api/main.go
283
api/main.go
@@ -11,6 +11,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@@ -31,6 +32,7 @@ func loadEnv() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataModel represents a single document in MongoDB
|
||||||
type DataModel struct {
|
type DataModel struct {
|
||||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
||||||
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
|
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
|
||||||
@@ -56,6 +58,13 @@ type StatusModel struct {
|
|||||||
STATUS string `json:"status" bson:"status"`
|
STATUS string `json:"status" bson:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CountResponse struct {
|
||||||
|
TotalEntries int64 `json:"total_entries"`
|
||||||
|
StatusCount map[string]int64 `json:"status_count"`
|
||||||
|
NSAPPCount map[string]int64 `json:"nsapp_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectDatabase initializes the MongoDB connection
|
||||||
func ConnectDatabase() {
|
func ConnectDatabase() {
|
||||||
loadEnv()
|
loadEnv()
|
||||||
|
|
||||||
@@ -78,6 +87,7 @@ func ConnectDatabase() {
|
|||||||
fmt.Println("Connected to MongoDB on 10.10.10.18")
|
fmt.Println("Connected to MongoDB on 10.10.10.18")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UploadJSON handles API requests and stores data as a document in MongoDB
|
||||||
func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
||||||
var input DataModel
|
var input DataModel
|
||||||
|
|
||||||
@@ -98,6 +108,7 @@ func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
|
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateStatus updates the status of a record based on RANDOM_ID
|
||||||
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
var input StatusModel
|
var input StatusModel
|
||||||
|
|
||||||
@@ -120,6 +131,7 @@ func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
|
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDataJSON fetches all data from MongoDB
|
||||||
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
||||||
var records []DataModel
|
var records []DataModel
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
@@ -144,6 +156,270 @@ func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(records)
|
json.NewEncoder(w).Encode(records)
|
||||||
}
|
}
|
||||||
|
func GetPaginatedData(w http.ResponseWriter, r *http.Request) {
|
||||||
|
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
||||||
|
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
if limit < 1 {
|
||||||
|
limit = 10
|
||||||
|
}
|
||||||
|
skip := (page - 1) * limit
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
options := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{}, options)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSummary(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
totalCount, err := collection.CountDocuments(ctx, bson.M{})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCount := make(map[string]int64)
|
||||||
|
nsappCount := make(map[string]int64)
|
||||||
|
|
||||||
|
pipeline := []bson.M{
|
||||||
|
{"$group": bson.M{"_id": "$status", "count": bson.M{"$sum": 1}}},
|
||||||
|
}
|
||||||
|
cursor, err := collection.Aggregate(ctx, pipeline)
|
||||||
|
if err == nil {
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var result struct {
|
||||||
|
ID string `bson:"_id"`
|
||||||
|
Count int64 `bson:"count"`
|
||||||
|
}
|
||||||
|
if err := cursor.Decode(&result); err == nil {
|
||||||
|
statusCount[result.ID] = result.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline = []bson.M{
|
||||||
|
{"$group": bson.M{"_id": "$nsapp", "count": bson.M{"$sum": 1}}},
|
||||||
|
}
|
||||||
|
cursor, err = collection.Aggregate(ctx, pipeline)
|
||||||
|
if err == nil {
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var result struct {
|
||||||
|
ID string `bson:"_id"`
|
||||||
|
Count int64 `bson:"count"`
|
||||||
|
}
|
||||||
|
if err := cursor.Decode(&result); err == nil {
|
||||||
|
nsappCount[result.ID] = result.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response := CountResponse{
|
||||||
|
TotalEntries: totalCount,
|
||||||
|
StatusCount: statusCount,
|
||||||
|
NSAPPCount: nsappCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByNsapp(w http.ResponseWriter, r *http.Request) {
|
||||||
|
nsapp := r.URL.Query().Get("nsapp")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"nsapp": nsapp})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByDateRange(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
startDate := r.URL.Query().Get("start_date")
|
||||||
|
endDate := r.URL.Query().Get("end_date")
|
||||||
|
|
||||||
|
if startDate == "" || endDate == "" {
|
||||||
|
http.Error(w, "Both start_date and end_date are required", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start, err := time.Parse("2006-01-02T15:04:05.999999+00:00", startDate+"T00:00:00+00:00")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid start_date format", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
end, err := time.Parse("2006-01-02T15:04:05.999999+00:00", endDate+"T23:59:59+00:00")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid end_date format", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{
|
||||||
|
"created_at": bson.M{
|
||||||
|
"$gte": start,
|
||||||
|
"$lte": end,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
func GetByStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
status := r.URL.Query().Get("status")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"status": status})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByOS(w http.ResponseWriter, r *http.Request) {
|
||||||
|
osType := r.URL.Query().Get("os_type")
|
||||||
|
osVersion := r.URL.Query().Get("os_version")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"os_type": osType, "os_version": osVersion})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetErrors(w http.ResponseWriter, r *http.Request) {
|
||||||
|
errorCount := make(map[string]int)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"error": bson.M{"$ne": ""}})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if record.ERROR != "" {
|
||||||
|
errorCount[record.ERROR]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorCountResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorCounts []ErrorCountResponse
|
||||||
|
for err, count := range errorCount {
|
||||||
|
errorCounts = append(errorCounts, ErrorCountResponse{
|
||||||
|
Error: err,
|
||||||
|
Count: count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(struct {
|
||||||
|
ErrorCounts []ErrorCountResponse `json:"error_counts"`
|
||||||
|
}{
|
||||||
|
ErrorCounts: errorCounts,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ConnectDatabase()
|
ConnectDatabase()
|
||||||
@@ -152,6 +428,13 @@ func main() {
|
|||||||
router.HandleFunc("/upload", UploadJSON).Methods("POST")
|
router.HandleFunc("/upload", UploadJSON).Methods("POST")
|
||||||
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
|
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
|
||||||
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
|
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
|
||||||
|
router.HandleFunc("/data/paginated", GetPaginatedData).Methods("GET")
|
||||||
|
router.HandleFunc("/data/summary", GetSummary).Methods("GET")
|
||||||
|
router.HandleFunc("/data/nsapp", GetByNsapp).Methods("GET")
|
||||||
|
router.HandleFunc("/data/date", GetByDateRange).Methods("GET")
|
||||||
|
router.HandleFunc("/data/status", GetByStatus).Methods("GET")
|
||||||
|
router.HandleFunc("/data/os", GetByOS).Methods("GET")
|
||||||
|
router.HandleFunc("/data/errors", GetErrors).Methods("GET")
|
||||||
|
|
||||||
c := cors.New(cors.Options{
|
c := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
|
|||||||
20
ct/grist.sh
20
ct/grist.sh
@@ -34,18 +34,36 @@ function update_script() {
|
|||||||
msg_ok "Stopped ${APP} Service"
|
msg_ok "Stopped ${APP} Service"
|
||||||
|
|
||||||
msg_info "Updating ${APP} to v${RELEASE}"
|
msg_info "Updating ${APP} to v${RELEASE}"
|
||||||
|
|
||||||
cd /opt
|
cd /opt
|
||||||
rm -rf grist_bak
|
rm -rf grist_bak
|
||||||
mv grist grist_bak
|
mv grist grist_bak
|
||||||
wget -q https://github.com/gristlabs/grist-core/archive/refs/tags/v${RELEASE}.zip
|
wget -q https://github.com/gristlabs/grist-core/archive/refs/tags/v${RELEASE}.zip
|
||||||
unzip -q v$RELEASE.zip
|
unzip -q v$RELEASE.zip
|
||||||
mv grist-core-${RELEASE} grist
|
mv grist-core-${RELEASE} grist
|
||||||
cp -n /opt/grist_bak/.env /opt/grist/.env
|
|
||||||
|
mkdir -p grist/docs
|
||||||
|
|
||||||
|
cp -n grist_bak/.env grist/.env || true
|
||||||
|
cp -r grist_bak/docs/* grist/docs/ || true
|
||||||
|
cp grist_bak/grist-sessions.db grist/grist-sessions.db || true
|
||||||
|
cp grist_bak/landing.db grist/landing.db || true
|
||||||
|
|
||||||
cd grist
|
cd grist
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
yarn install >/dev/null 2>&1
|
yarn install >/dev/null 2>&1
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
msg_info "Building"
|
||||||
yarn run build:prod >/dev/null 2>&1
|
yarn run build:prod >/dev/null 2>&1
|
||||||
|
msg_ok "Done building"
|
||||||
|
|
||||||
|
msg_info "Installing Python"
|
||||||
yarn run install:python >/dev/null 2>&1
|
yarn run install:python >/dev/null 2>&1
|
||||||
|
msg_ok "Installed Python"
|
||||||
|
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
|
|
||||||
msg_ok "Updated ${APP} to v${RELEASE}"
|
msg_ok "Updated ${APP} to v${RELEASE}"
|
||||||
|
|
||||||
msg_info "Starting ${APP} Service"
|
msg_info "Starting ${APP} Service"
|
||||||
|
|||||||
64
ct/homarr.sh
64
ct/homarr.sh
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2025 tteck
|
# Copyright (c) 2021-2025 tteck
|
||||||
# Author: tteck (tteckster) | Co-Author: MickLesk (Canbiz)
|
# Author: tteck (tteckster) | Co-Author: MickLesk (Canbiz) | Co-Author: CrazyWolf13
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://homarr.dev/
|
# Source: https://homarr.dev/
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ var_version="12"
|
|||||||
var_unprivileged="1"
|
var_unprivileged="1"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
|
|
||||||
variables
|
variables
|
||||||
color
|
color
|
||||||
catch_errors
|
catch_errors
|
||||||
@@ -33,11 +34,48 @@ if [[ -f /opt/homarr/database/db.sqlite ]]; then
|
|||||||
msg_error " - https://github.com/community-scripts/ProxmoxVE/discussions/1551"
|
msg_error " - https://github.com/community-scripts/ProxmoxVE/discussions/1551"
|
||||||
msg_error " - https://homarr.dev/docs/getting-started/after-the-installation/#importing-a-zip-from-version-before-100"
|
msg_error " - https://homarr.dev/docs/getting-started/after-the-installation/#importing-a-zip-from-version-before-100"
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f /opt/run_homarr.sh ]]; then
|
||||||
|
msg_info "Detected outdated and missing service files"
|
||||||
|
msg_error "Warning - The port of homarr changed from 3000 to 7575"
|
||||||
|
apt-get install -y nginx gettext openssl gpg &>/dev/null
|
||||||
|
sed -i '/^NODE_ENV=/d' /opt/homarr/.env && echo "NODE_ENV='production'" >> /opt/homarr/.env
|
||||||
|
sed -i '/^DB_DIALECT=/d' /opt/homarr/.env && echo "DB_DIALECT='sqlite'" >> /opt/homarr/.env
|
||||||
|
cat <<'EOF' >/opt/run_homarr.sh
|
||||||
|
#!/bin/bash
|
||||||
|
export DB_DIALECT='sqlite'
|
||||||
|
export AUTH_SECRET=$(openssl rand -base64 32)
|
||||||
|
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
|
||||||
|
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
|
||||||
|
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
|
||||||
|
nginx -g 'daemon off;' &
|
||||||
|
redis-server /opt/homarr/packages/redis/redis.conf &
|
||||||
|
node apps/tasks/tasks.cjs &
|
||||||
|
node apps/websocket/wssServer.cjs &
|
||||||
|
node apps/nextjs/server.js & PID=$!
|
||||||
|
wait $PID
|
||||||
|
EOF
|
||||||
|
chmod +x /opt/run_homarr.sh
|
||||||
|
rm /etc/systemd/system/homarr.service
|
||||||
|
cat <<EOF >/etc/systemd/system/homarr.service
|
||||||
|
[Unit]
|
||||||
|
Description=Homarr Service
|
||||||
|
After=network.target
|
||||||
|
[Service]
|
||||||
|
Type=exec
|
||||||
|
WorkingDirectory=/opt/homarr
|
||||||
|
EnvironmentFile=-/opt/homarr/.env
|
||||||
|
ExecStart=/opt/run_homarr.sh
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
msg_ok "Updated Services"
|
||||||
|
systemctl daemon-reload
|
||||||
fi
|
fi
|
||||||
RELEASE=$(curl -s https://api.github.com/repos/homarr-labs/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
RELEASE=$(curl -s https://api.github.com/repos/homarr-labs/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services (Patience)"
|
||||||
systemctl stop homarr
|
systemctl stop homarr
|
||||||
msg_ok "Services Stopped"
|
msg_ok "Services Stopped"
|
||||||
|
|
||||||
@@ -46,7 +84,7 @@ fi
|
|||||||
cp /opt/homarr/.env /opt/homarr-data-backup/.env
|
cp /opt/homarr/.env /opt/homarr-data-backup/.env
|
||||||
msg_ok "Backup Data"
|
msg_ok "Backup Data"
|
||||||
|
|
||||||
msg_info "Updating ${APP} to v${RELEASE}"
|
msg_info "Updating and rebuilding ${APP} to v${RELEASE} (Patience)"
|
||||||
wget -q "https://github.com/homarr-labs/homarr/archive/refs/tags/v${RELEASE}.zip"
|
wget -q "https://github.com/homarr-labs/homarr/archive/refs/tags/v${RELEASE}.zip"
|
||||||
unzip -q v${RELEASE}.zip
|
unzip -q v${RELEASE}.zip
|
||||||
rm -rf v${RELEASE}.zip
|
rm -rf v${RELEASE}.zip
|
||||||
@@ -55,9 +93,23 @@ fi
|
|||||||
mv /opt/homarr-data-backup/.env /opt/homarr/.env
|
mv /opt/homarr-data-backup/.env /opt/homarr/.env
|
||||||
cd /opt/homarr
|
cd /opt/homarr
|
||||||
pnpm install &>/dev/null
|
pnpm install &>/dev/null
|
||||||
pnpm run db:migration:sqlite:run &>/dev/null
|
|
||||||
pnpm build &>/dev/null
|
pnpm build &>/dev/null
|
||||||
mkdir build
|
cp /opt/homarr/apps/nextjs/next.config.ts .
|
||||||
|
cp /opt/homarr/apps/nextjs/package.json .
|
||||||
|
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
|
||||||
|
cp -r /opt/homarr/apps/nextjs/.next/standalone/* /opt/homarr
|
||||||
|
mkdir -p /appdata/redis
|
||||||
|
cp /opt/homarr/packages/redis/redis.conf /opt/homarr/redis.conf
|
||||||
|
rm /etc/nginx/nginx.conf
|
||||||
|
mkdir -p /etc/nginx/templates
|
||||||
|
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
|
||||||
|
|
||||||
|
mkdir -p /opt/homarr/apps/cli
|
||||||
|
cp /opt/homarr/packages/cli/cli.cjs /opt/homarr/apps/cli/cli.cjs
|
||||||
|
echo $'#!/bin/bash\ncd /opt/homarr/apps/cli && node ./cli.cjs "$@"' > /usr/bin/homarr
|
||||||
|
chmod +x /usr/bin/homarr
|
||||||
|
|
||||||
|
mkdir /opt/homarr/build
|
||||||
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
|
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Updated ${APP}"
|
||||||
@@ -79,4 +131,4 @@ description
|
|||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7575${CL}"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2025 tteck
|
# Copyright (c) 2021-2025 tteck
|
||||||
# Author: tteck (tteckster)
|
# Author: tteck (tteckster) | Co-Author Slaviša Arežina (tremor021)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://magicmirror.builders/
|
# Source: https://magicmirror.builders/
|
||||||
|
|
||||||
@@ -27,18 +27,45 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
if [[ "$(node -v | cut -d 'v' -f 2)" == "18."* ]]; then
|
RELEASE=$(curl -s https://api.github.com/repos/MagicMirrorOrg/MagicMirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
if ! command -v npm >/dev/null 2>&1; then
|
if [[ ! -f /opt/${APP}_version.txt ]]; then touch /opt/${APP}_version.txt; fi
|
||||||
echo "Installing NPM..."
|
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||||
apt-get install -y npm >/dev/null 2>&1
|
msg_info "Stopping Service"
|
||||||
echo "Installed NPM..."
|
systemctl stop magicmirror
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Updating ${APP} to v${RELEASE}"
|
||||||
|
mkdir /opt/magicmirror-backup
|
||||||
|
cp /opt/magicmirror/config/config.js /opt/magicmirror-backup
|
||||||
|
if [[ -f /opt/magicmirror/css/custom.css ]]; then
|
||||||
|
cp /opt/magicmirror/css/custom.css /opt/magicmirror-backup
|
||||||
fi
|
fi
|
||||||
|
cp -r /opt/magicmirror/modules /opt/magicmirror-backup
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
wget -q "https://github.com/MagicMirrorOrg/MagicMirror/archive/refs/tags/v${RELEASE}.tar.gz" -O "$temp_file"
|
||||||
|
tar -xzf "$temp_file"
|
||||||
|
rm -rf /opt/magicmirror
|
||||||
|
mv MagicMirror-${RELEASE} /opt/magicmirror
|
||||||
|
cd /opt/magicmirror
|
||||||
|
npm run install-mm &> /dev/null
|
||||||
|
cp /opt/magicmirror-backup/config.js /opt/magicmirror/config/
|
||||||
|
if [[ -f /opt/magicmirror-backup/custom.css ]]; then
|
||||||
|
cp /opt/magicmirror-backup/custom.css /opt/magicmirror/css/
|
||||||
|
fi
|
||||||
|
echo "${RELEASE}" >"/opt/${APP}_version.txt"
|
||||||
|
msg_ok "Updated ${APP} to v${RELEASE}"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start magicmirror
|
||||||
|
msg_ok "Started Service"
|
||||||
|
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
rm -f $temp_file
|
||||||
|
msg_ok "Cleaned"
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at v${RELEASE}."
|
||||||
fi
|
fi
|
||||||
msg_info "Updating ${APP} LXC"
|
|
||||||
cd /opt/magicmirror
|
|
||||||
git pull &>/dev/null
|
|
||||||
npm install --only=prod --omit=dev &>/dev/null
|
|
||||||
msg_ok "Updated Successfully"
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ chmod -R g+rX /opt/freshrss
|
|||||||
chmod -R g+w /opt/freshrss/data/
|
chmod -R g+w /opt/freshrss/data/
|
||||||
msg_ok "Installed FreshRSS"
|
msg_ok "Installed FreshRSS"
|
||||||
|
|
||||||
|
msg_info "Setting up cron job for feed refresh"
|
||||||
|
cat <<EOF >/etc/cron.d/freshrss-actualize
|
||||||
|
*/15 * * * * www-data /bin/php -f /opt/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
|
||||||
|
EOF
|
||||||
|
chmod 644 /etc/cron.d/freshrss-actualize
|
||||||
|
msg_ok "Set up Cron - if you need to modify the timing edit file /etc/cron.d/freshrss-actualize"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
cat <<EOF >/etc/apache2/sites-available/freshrss.conf
|
cat <<EOF >/etc/apache2/sites-available/freshrss.conf
|
||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Copyright (c) 2021-2025 community-scripts ORG
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
# Author: MickLesk (Canbiz)
|
# Author: MickLesk (Canbiz)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/ajnart/homarr
|
# Source: https://github.com/homarr-labs/homarr
|
||||||
|
|
||||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
||||||
color
|
color
|
||||||
@@ -20,10 +20,13 @@ $STD apt-get install -y \
|
|||||||
curl \
|
curl \
|
||||||
redis-server \
|
redis-server \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
gnupg \
|
gpg \
|
||||||
make \
|
make \
|
||||||
g++ \
|
g++ \
|
||||||
build-essential
|
build-essential \
|
||||||
|
nginx \
|
||||||
|
gettext \
|
||||||
|
openssl
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Setting up Node.js Repository"
|
msg_info "Setting up Node.js Repository"
|
||||||
@@ -46,27 +49,56 @@ unzip -q v${RELEASE}.zip
|
|||||||
mv homarr-${RELEASE} /opt/homarr
|
mv homarr-${RELEASE} /opt/homarr
|
||||||
mkdir -p /opt/homarr_db
|
mkdir -p /opt/homarr_db
|
||||||
touch /opt/homarr_db/db.sqlite
|
touch /opt/homarr_db/db.sqlite
|
||||||
AUTH_SECRET="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
|
|
||||||
SECRET_ENCRYPTION_KEY="$(openssl rand -hex 32)"
|
SECRET_ENCRYPTION_KEY="$(openssl rand -hex 32)"
|
||||||
|
cd /opt/homarr
|
||||||
cat <<EOF >/opt/homarr/.env
|
cat <<EOF >/opt/homarr/.env
|
||||||
AUTH_SECRET='${AUTH_SECRET}'
|
|
||||||
DB_DRIVER='better-sqlite3'
|
DB_DRIVER='better-sqlite3'
|
||||||
|
DB_DIALECT='sqlite'
|
||||||
SECRET_ENCRYPTION_KEY='${SECRET_ENCRYPTION_KEY}'
|
SECRET_ENCRYPTION_KEY='${SECRET_ENCRYPTION_KEY}'
|
||||||
DB_URL='/opt/homarr_db/db.sqlite'
|
DB_URL='/opt/homarr_db/db.sqlite'
|
||||||
TURBO_TELEMETRY_DISABLED=1
|
TURBO_TELEMETRY_DISABLED=1
|
||||||
|
AUTH_PROVIDERS='credentials'
|
||||||
|
NODE_ENV='production'
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cd /opt/homarr
|
|
||||||
$STD pnpm install
|
$STD pnpm install
|
||||||
$STD pnpm run db:migration:sqlite:run
|
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
mkdir build
|
|
||||||
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
|
|
||||||
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
|
|
||||||
msg_ok "Installed Homarr"
|
msg_ok "Installed Homarr"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Copying build and config files"
|
||||||
|
cp /opt/homarr/apps/nextjs/next.config.ts .
|
||||||
|
cp /opt/homarr/apps/nextjs/package.json .
|
||||||
|
cp -r /opt/homarr/packages/db/migrations /opt/homarr_db/migrations
|
||||||
|
cp -r /opt/homarr/apps/nextjs/.next/standalone/* /opt/homarr
|
||||||
|
mkdir -p /appdata/redis
|
||||||
|
cp /opt/homarr/packages/redis/redis.conf /opt/homarr/redis.conf
|
||||||
|
mkdir -p /etc/nginx/templates
|
||||||
|
rm /etc/nginx/nginx.conf
|
||||||
|
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
|
||||||
|
mkdir -p /opt/homarr/apps/cli
|
||||||
|
cp /opt/homarr/packages/cli/cli.cjs /opt/homarr/apps/cli/cli.cjs
|
||||||
|
echo $'#!/bin/bash\ncd /opt/homarr/apps/cli && node ./cli.cjs "$@"' > /usr/bin/homarr
|
||||||
|
chmod +x /usr/bin/homarr
|
||||||
|
mkdir /opt/homarr/build
|
||||||
|
cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node
|
||||||
|
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
|
||||||
|
msg_ok "Finished copying"
|
||||||
|
|
||||||
|
msg_info "Creating Services"
|
||||||
|
cat <<'EOF' >/opt/run_homarr.sh
|
||||||
|
#!/bin/bash
|
||||||
|
export DB_DIALECT='sqlite'
|
||||||
|
export AUTH_SECRET=$(openssl rand -base64 32)
|
||||||
|
node /opt/homarr_db/migrations/$DB_DIALECT/migrate.cjs /opt/homarr_db/migrations/$DB_DIALECT
|
||||||
|
export HOSTNAME=$(ip route get 1.1.1.1 | grep -oP 'src \K[^ ]+')
|
||||||
|
envsubst '${HOSTNAME}' < /etc/nginx/templates/nginx.conf > /etc/nginx/nginx.conf
|
||||||
|
nginx -g 'daemon off;' &
|
||||||
|
redis-server /opt/homarr/packages/redis/redis.conf &
|
||||||
|
node apps/tasks/tasks.cjs &
|
||||||
|
node apps/websocket/wssServer.cjs &
|
||||||
|
node apps/nextjs/server.js & PID=$!
|
||||||
|
wait $PID
|
||||||
|
EOF
|
||||||
|
chmod +x /opt/run_homarr.sh
|
||||||
cat <<EOF >/etc/systemd/system/homarr.service
|
cat <<EOF >/etc/systemd/system/homarr.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Homarr Service
|
Description=Homarr Service
|
||||||
@@ -76,7 +108,7 @@ After=network.target
|
|||||||
Type=exec
|
Type=exec
|
||||||
WorkingDirectory=/opt/homarr
|
WorkingDirectory=/opt/homarr
|
||||||
EnvironmentFile=-/opt/homarr/.env
|
EnvironmentFile=-/opt/homarr/.env
|
||||||
ExecStart=/usr/bin/pnpm start
|
ExecStart=/opt/run_homarr.sh
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2025 tteck
|
# Copyright (c) 2021-2025 tteck
|
||||||
# Author: tteck (tteckster)
|
# Author: tteck (tteckster) | Co-Author Slaviša Arežina (tremor021)
|
||||||
# License: MIT
|
# License: MIT
|
||||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://magicmirror.builders/
|
||||||
|
|
||||||
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"
|
||||||
color
|
color
|
||||||
@@ -14,12 +15,11 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt-get install -y curl
|
$STD apt-get install -y \
|
||||||
$STD apt-get install -y sudo
|
curl \
|
||||||
$STD apt-get install -y mc
|
sudo \
|
||||||
$STD apt-get install -y git
|
mc \
|
||||||
$STD apt-get install -y ca-certificates
|
gnupg
|
||||||
$STD apt-get install -y gnupg
|
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Setting up Node.js Repository"
|
msg_info "Setting up Node.js Repository"
|
||||||
@@ -33,14 +33,14 @@ $STD apt-get update
|
|||||||
$STD apt-get install -y nodejs
|
$STD apt-get install -y nodejs
|
||||||
msg_ok "Installed Node.js"
|
msg_ok "Installed Node.js"
|
||||||
|
|
||||||
msg_info "Setting up MagicMirror Repository"
|
msg_info "Setup MagicMirror"
|
||||||
$STD git clone https://github.com/MichMich/MagicMirror /opt/magicmirror
|
temp_file=$(mktemp)
|
||||||
msg_ok "Set up MagicMirror Repository"
|
RELEASE=$(curl -s https://api.github.com/repos/MagicMirrorOrg/MagicMirror/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||||
|
wget -q "https://github.com/MagicMirrorOrg/MagicMirror/archive/refs/tags/v${RELEASE}.tar.gz" -O "$temp_file"
|
||||||
msg_info "Installing MagicMirror"
|
tar -xzf "$temp_file"
|
||||||
|
mv MagicMirror-${RELEASE} /opt/magicmirror
|
||||||
cd /opt/magicmirror
|
cd /opt/magicmirror
|
||||||
$STD npm install --only=prod --omit=dev
|
$STD npm run install-mm
|
||||||
|
|
||||||
cat <<EOF >/opt/magicmirror/config/config.js
|
cat <<EOF >/opt/magicmirror/config/config.js
|
||||||
let config = {
|
let config = {
|
||||||
address: "0.0.0.0",
|
address: "0.0.0.0",
|
||||||
@@ -130,11 +130,12 @@ let config = {
|
|||||||
/*************** DO NOT EDIT THE LINE BELOW ***************/
|
/*************** DO NOT EDIT THE LINE BELOW ***************/
|
||||||
if (typeof module !== "undefined") {module.exports = config;}
|
if (typeof module !== "undefined") {module.exports = config;}
|
||||||
EOF
|
EOF
|
||||||
msg_ok "Installed MagicMirror"
|
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
|
||||||
|
msg_ok "Setup MagicMirror"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
service_path="/etc/systemd/system/magicmirror.service"
|
cat <<EOF >/etc/systemd/system/magicmirror.service
|
||||||
echo "[Unit]
|
[Unit]
|
||||||
Description=Magic Mirror
|
Description=Magic Mirror
|
||||||
After=network.target
|
After=network.target
|
||||||
StartLimitIntervalSec=0
|
StartLimitIntervalSec=0
|
||||||
@@ -145,17 +146,19 @@ Restart=always
|
|||||||
RestartSec=1
|
RestartSec=1
|
||||||
User=root
|
User=root
|
||||||
WorkingDirectory=/opt/magicmirror/
|
WorkingDirectory=/opt/magicmirror/
|
||||||
ExecStart=/usr/bin/node serveronly
|
ExecStart=/usr/bin/npm run server
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target" >$service_path
|
WantedBy=multi-user.target
|
||||||
$STD systemctl enable --now magicmirror
|
EOF
|
||||||
|
systemctl enable --now magicmirror
|
||||||
msg_ok "Created Service"
|
msg_ok "Created Service"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
msg_info "Cleaning up"
|
||||||
|
rm -rf $temp_file
|
||||||
$STD apt-get -y autoremove
|
$STD apt-get -y autoremove
|
||||||
$STD apt-get -y autoclean
|
$STD apt-get -y autoclean
|
||||||
msg_ok "Cleaned"
|
msg_ok "Cleaned"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"interface_port": null,
|
"interface_port": null,
|
||||||
"documentation": null,
|
"documentation": null,
|
||||||
"website": "https://www.debian.org/",
|
"website": "https://www.debian.org/",
|
||||||
"logo": "https://seeklogo.com/images/D/debian-logo-C136FDAF9E-seeklogo.com.png",
|
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/debian.svg",
|
||||||
"description": "Debian Linux is a distribution that emphasizes free software. It supports many hardware platforms",
|
"description": "Debian Linux is a distribution that emphasizes free software. It supports many hardware platforms",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"interface_port": null,
|
"interface_port": null,
|
||||||
"documentation": null,
|
"documentation": null,
|
||||||
"website": "https://www.debian.org/",
|
"website": "https://www.debian.org/",
|
||||||
"logo": "https://seeklogo.com/images/D/debian-logo-C136FDAF9E-seeklogo.com.png",
|
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/debian.svg",
|
||||||
"description": "Debian Linux is a distribution that emphasizes free software. It supports many hardware platforms.",
|
"description": "Debian Linux is a distribution that emphasizes free software. It supports many hardware platforms.",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
{
|
{
|
||||||
"text": "Database credentials: `cat ~/freshrss.creds`",
|
"text": "Database credentials: `cat ~/freshrss.creds`",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Per FreshRSS documentation, a cron job to actualize FreshRSS will be setup at `/etc/cron.d/freshrss-actualize`. This can be adjusted as needed",
|
||||||
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"interface_port": 9000,
|
"interface_port": 9000,
|
||||||
"documentation": "https://go2docs.graylog.org/current/home.htm",
|
"documentation": "https://go2docs.graylog.org/current/home.htm",
|
||||||
"website": "https://graylog.org/",
|
"website": "https://graylog.org/",
|
||||||
"logo": "https://graylog.org/wp-content/uploads/2023/11/gl-logo-horiz-all-white-1200w-300x96.png.webp",
|
"logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/graylog.svg",
|
||||||
"description": "Graylog is a free and open log management platform.",
|
"description": "Graylog is a free and open log management platform.",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"type": "ct",
|
"type": "ct",
|
||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": false,
|
"privileged": false,
|
||||||
"interface_port": 3000,
|
"interface_port": 7575,
|
||||||
"documentation": null,
|
"documentation": null,
|
||||||
"website": "https://homarr.dev/",
|
"website": "https://homarr.dev/",
|
||||||
"logo": "https://raw.githubusercontent.com/loganmarchione/homelab-svg-assets/main/assets/homarr.svg",
|
"logo": "https://raw.githubusercontent.com/loganmarchione/homelab-svg-assets/main/assets/homarr.svg",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "RustDesk Server",
|
"name": "RustDesk Server",
|
||||||
"slug": "rustdesk-server",
|
"slug": "rustdeskserver",
|
||||||
"categories": [
|
"categories": [
|
||||||
21
|
21
|
||||||
],
|
],
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"text": "Check documentation on how to configure RustDesk Server. `https://rustdesk.com/docs/en/`",
|
"text": "Check our configuration guide for help: `https://github.com/community-scripts/ProxmoxVE/discussions/2388`",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ post_to_api() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
RESPONSE=$(curl -s -o response.txt -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$JSON_PAYLOAD") || true
|
-d "$JSON_PAYLOAD") || true
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ post_to_api_vm() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
RESPONSE=$(curl -s -o response.txt -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$JSON_PAYLOAD") || true
|
-d "$JSON_PAYLOAD") || true
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ post_update_to_api() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
RESPONSE=$(curl -s -o response.txt -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
RESPONSE=$(curl -s -w "%{http_code}" -L -X POST "$API_URL" --post301 --post302 \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$JSON_PAYLOAD") || true
|
-d "$JSON_PAYLOAD") || true
|
||||||
|
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ else
|
|||||||
fi
|
fi
|
||||||
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
||||||
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
||||||
msg_info "Retrieving the URL for the Ubuntu 24.0 Disk Image"
|
msg_info "Retrieving the URL for the Ubuntu 24.10 Disk Image"
|
||||||
URL=https://cloud-images.ubuntu.com/oracular/current/oracular-server-cloudimg-amd64.img
|
URL=https://cloud-images.ubuntu.com/oracular/current/oracular-server-cloudimg-amd64.img
|
||||||
sleep 2
|
sleep 2
|
||||||
msg_ok "${CL}${BL}${URL}${CL}"
|
msg_ok "${CL}${BL}${URL}${CL}"
|
||||||
|
|||||||
Reference in New Issue
Block a user