mirror of
https://github.com/myronblair/proxmox-config
synced 2026-06-30 15:59:57 -05:00
[pve] Weekly backup 2026-06-08 — 42 files changed, 869 insertions(+)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/update-lxcs-cron.sh)" >>/var/log/update-lxcs-cron.log 2>/dev/null
|
||||
0 0 * * 0 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/update-lxcs-cron.sh)" >>/var/log/update-lxcs-cron.log 2>/dev/null
|
||||
* * * * * /usr/bin/python3 /usr/local/bin/jarvis-ping-probe.py >> /var/log/jarvis-ping-probe.log 2>&1
|
||||
*/3 * * * * /usr/local/bin/jarvis-netscan.sh >>/var/log/jarvis-netscan.log 2>&1
|
||||
* * * * * /usr/local/bin/jarvis-phone-probe.sh >/dev/null 2>&1
|
||||
0 3 * * 0 /usr/local/bin/proxmox-backup >> /var/log/proxmox-backup.log 2>&1
|
||||
@@ -0,0 +1 @@
|
||||
pve
|
||||
@@ -0,0 +1,11 @@
|
||||
127.0.0.1 localhost.localdomain localhost
|
||||
10.48.200.90 pve.orbishsoting.com pve
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
|
||||
::1 ip6-localhost ip6-loopback
|
||||
fe00::0 ip6-localnet
|
||||
ff00::0 ip6-mcastprefix
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
ff02::3 ip6-allhosts
|
||||
@@ -0,0 +1,33 @@
|
||||
# network interface settings; autogenerated
|
||||
# Please do NOT modify this file directly, unless you know what
|
||||
# you're doing.
|
||||
#
|
||||
# If you want to manage parts of the network configuration manually,
|
||||
# please utilize the 'source' or 'source-directory' directives to do
|
||||
# so.
|
||||
# PVE will preserve these directives, but will NOT read its network
|
||||
# configuration from sourced files, so do not attempt to move any of
|
||||
# the PVE managed interfaces into external files!
|
||||
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
iface nic0 inet manual
|
||||
|
||||
iface nic1 inet manual
|
||||
|
||||
iface nic2 inet manual
|
||||
|
||||
iface nic3 inet manual
|
||||
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 10.48.200.90/24
|
||||
gateway 10.48.200.1
|
||||
bridge-ports nic0
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
bridge-vlan-aware yes
|
||||
bridge-vids 2-4094
|
||||
|
||||
source /etc/network/interfaces.d/*
|
||||
@@ -0,0 +1,7 @@
|
||||
# resolv.conf(5) file generated by tailscale
|
||||
# For more info, see https://tailscale.com/s/resolvconf-overwrite
|
||||
# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN
|
||||
|
||||
nameserver 100.100.100.100
|
||||
nameserver fd7a:115c:a1e0::53
|
||||
search tail7dfd0c.ts.net
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
# JARVIS Network Scanner — runs on PVE1, pushes nmap results to JARVIS
|
||||
# Cron: */3 * * * * /usr/local/bin/jarvis-netscan.sh >/dev/null 2>&1
|
||||
|
||||
JARVIS_URL="https://165.22.1.228"
|
||||
JARVIS_HOST="jarvis.orbishosting.com"
|
||||
REG_KEY="f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518"
|
||||
SUBNET="10.48.200.0/24"
|
||||
|
||||
TMPFILE=$(mktemp)
|
||||
nmap -sn --send-ip "$SUBNET" 2>/dev/null > "$TMPFILE"
|
||||
|
||||
if [ ! -s "$TMPFILE" ]; then
|
||||
echo "$(date): nmap produced no output" >&2
|
||||
rm -f "$TMPFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JSON=$(python3 - "$TMPFILE" <<'PYEOF'
|
||||
import sys, re, json
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
data = f.read()
|
||||
|
||||
devices = []
|
||||
cur = None
|
||||
|
||||
for line in data.splitlines():
|
||||
line = line.strip()
|
||||
m = re.match(r'Nmap scan report for (?:(\S+) \()?(\d+\.\d+\.\d+\.\d+)\)?', line)
|
||||
if m:
|
||||
if cur:
|
||||
devices.append(cur)
|
||||
hn = m.group(1) if m.group(1) and m.group(1) != m.group(2) else ''
|
||||
cur = {'ip': m.group(2), 'hostname': hn, 'mac': '', 'vendor': ''}
|
||||
elif cur:
|
||||
m2 = re.match(r'MAC Address: ([0-9A-Fa-f:]{17}) \(([^)]+)\)', line)
|
||||
if m2:
|
||||
cur['mac'] = m2.group(1).lower()
|
||||
cur['vendor'] = '' if m2.group(2) == 'Unknown' else m2.group(2)
|
||||
|
||||
if cur:
|
||||
devices.append(cur)
|
||||
|
||||
print(json.dumps({'devices': devices}))
|
||||
PYEOF
|
||||
)
|
||||
|
||||
rm -f "$TMPFILE"
|
||||
|
||||
if [ -z "$JSON" ]; then
|
||||
echo "$(date): JSON parse failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RESPONSE=$(curl -sk --max-time 15 \
|
||||
-X POST "$JARVIS_URL/api/netscan" \
|
||||
-H "Host: $JARVIS_HOST" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Registration-Key: $REG_KEY" \
|
||||
-d "$JSON" 2>/dev/null)
|
||||
|
||||
echo "$(date): $RESPONSE"
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
# JARVIS VoIP Phone Probe — runs every minute on PVE1
|
||||
# Pings all Yealink phones + checks FusionPBX SIP registration (read-only)
|
||||
# 200.3 is on an external FusionPBX — ping only, no SIP check
|
||||
|
||||
JARVIS_URL="https://165.22.1.228"
|
||||
JARVIS_HOST="jarvis.orbishosting.com"
|
||||
REG_KEY="f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518"
|
||||
FUSION_HOST="134.209.72.226"
|
||||
|
||||
# IP|alias|extension(none=skip SIP check)|mac
|
||||
PHONES=(
|
||||
"10.48.200.2|Yealink — Myron Main (Ext 1000)|1000|80:5e:c0:35:04:77"
|
||||
"10.48.200.3|Yealink — United Mirror & Glass (External SIP)|none|c4:fc:22:28:63:71"
|
||||
"10.48.200.43|Yealink T48S — Tommy Main (Ext 1001)|1001|80:5e:0c:15:0c:4f"
|
||||
"10.48.200.86|Yealink — Myron Vanguard WiFi (Offline During Work Hrs)|none|"
|
||||
"10.48.200.65|Yealink — Myron Vanguard Work (Ext 1003)|1003|c4:fc:22:13:e1:89"
|
||||
)
|
||||
|
||||
# Get SIP registrations from FusionPBX (read-only)
|
||||
REG_OUTPUT=$(ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -o BatchMode=yes \
|
||||
root@$FUSION_HOST "fs_cli -x 'show registrations'" 2>/dev/null || echo "")
|
||||
|
||||
DEVICES="["
|
||||
FIRST=1
|
||||
for PHONE in "${PHONES[@]}"; do
|
||||
IFS='|' read -r IP ALIAS EXT MAC <<< "$PHONE"
|
||||
|
||||
# Ping probe
|
||||
if ping -c 1 -W 2 "$IP" > /dev/null 2>&1; then
|
||||
STATUS="online"
|
||||
else
|
||||
STATUS="offline"
|
||||
fi
|
||||
|
||||
# SIP check — skip for external phones (ext=none)
|
||||
if [ "$EXT" = "none" ]; then
|
||||
SIP="external"
|
||||
elif [ -n "$REG_OUTPUT" ] && echo "$REG_OUTPUT" | grep -q "^${EXT},"; then
|
||||
SIP="registered"
|
||||
else
|
||||
SIP="unregistered"
|
||||
fi
|
||||
|
||||
[ $FIRST -eq 0 ] && DEVICES+=","
|
||||
DEVICES+="{\"ip\":\"$IP\",\"alias\":\"$ALIAS\",\"mac\":\"$MAC\",\"vendor\":\"Yealink\",\"status\":\"$STATUS\",\"sip_status\":\"$SIP\",\"extension\":\"$EXT\"}"
|
||||
FIRST=0
|
||||
done
|
||||
DEVICES+="]"
|
||||
|
||||
curl -sk --max-time 10 \
|
||||
-X POST "$JARVIS_URL/api/netscan" \
|
||||
-H "Host: $JARVIS_HOST" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Registration-Key: $REG_KEY" \
|
||||
-d "{\"devices\":$DEVICES}" > /dev/null 2>&1
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
JARVIS Ping Probe — runs on PVE1 (10.48.200.90), which is on the LAN.
|
||||
Pings devices that can't run the full agent, then calls JARVIS heartbeat
|
||||
on their behalf so the dashboard shows live status.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
import ssl
|
||||
|
||||
JARVIS_URL = "https://165.22.1.228"
|
||||
HOST_HEADER = "jarvis.orbishosting.com"
|
||||
|
||||
# Devices to probe: agent_id → api_key
|
||||
DEVICES = {
|
||||
"fortigate_gw": "00103aea6fcbf837bc55e11b445a3620",
|
||||
"yealink_t48s": "2bf8bd7ca8dd31c28fd16aa956e15f88",
|
||||
"homeassistant_ha": "6f8077dee7a7b4af202bc80886f1223d",
|
||||
}
|
||||
|
||||
# Map agent_id → IP (for ping)
|
||||
IPS = {
|
||||
"fortigate_gw": "10.48.200.1",
|
||||
"yealink_t48s": "10.48.200.43",
|
||||
"homeassistant_ha": "10.48.200.97",
|
||||
}
|
||||
|
||||
def ping(ip: str) -> bool:
|
||||
result = subprocess.run(
|
||||
["ping", "-c", "1", "-W", "2", ip],
|
||||
capture_output=True, timeout=5
|
||||
)
|
||||
return result.returncode == 0
|
||||
|
||||
def heartbeat(agent_id: str, api_key: str, alive: bool):
|
||||
# If device is down we still send heartbeat so JARVIS updates last_seen
|
||||
# and sets status based on the alive flag via the metric payload
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
payload = json.dumps({}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{JARVIS_URL}/api/agent/heartbeat",
|
||||
data=payload, method="POST"
|
||||
)
|
||||
req.add_header("Content-Type", "application/json")
|
||||
req.add_header("X-Agent-Key", api_key)
|
||||
req.add_header("Host", HOST_HEADER)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=10, context=ctx):
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def update_status(agent_id: str, api_key: str, status: str):
|
||||
"""Push a minimal metric so JARVIS knows if device is up or down."""
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
payload = json.dumps({
|
||||
"type": "system",
|
||||
"data": {
|
||||
"hostname": agent_id,
|
||||
"cpu_percent": 0,
|
||||
"ping_only": True,
|
||||
"ping_status": status,
|
||||
}
|
||||
}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{JARVIS_URL}/api/agent/metrics",
|
||||
data=payload, method="POST"
|
||||
)
|
||||
req.add_header("Content-Type", "application/json")
|
||||
req.add_header("X-Agent-Key", api_key)
|
||||
req.add_header("Host", HOST_HEADER)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=10, context=ctx):
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def main():
|
||||
for agent_id, api_key in DEVICES.items():
|
||||
ip = IPS.get(agent_id, "")
|
||||
alive = ping(ip) if ip else False
|
||||
status = "online" if alive else "offline"
|
||||
print(f"{agent_id} ({ip}): {status}", flush=True)
|
||||
heartbeat(agent_id, api_key, alive)
|
||||
if alive:
|
||||
update_status(agent_id, api_key, status)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
WEB_JS=/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
|
||||
if [ -s "$WEB_JS" ] && ! grep -q NoMoreNagging "$WEB_JS"; then
|
||||
echo "Patching Web UI nag..."
|
||||
sed -i -e "/data\.status/ s/!//" -e "/data\.status/ s/active/NoMoreNagging/" "$WEB_JS"
|
||||
fi
|
||||
|
||||
MOBILE_TPL=/usr/share/pve-yew-mobile-gui/index.html.tpl
|
||||
MARKER="<!-- MANAGED BLOCK FOR MOBILE NAG -->"
|
||||
if [ -f "$MOBILE_TPL" ] && ! grep -q "$MARKER" "$MOBILE_TPL"; then
|
||||
echo "Patching Mobile UI nag..."
|
||||
printf "%s\n" \
|
||||
"$MARKER" \
|
||||
"<script>" \
|
||||
" function removeSubscriptionElements() {" \
|
||||
" // --- Remove subscription dialogs ---" \
|
||||
" const dialogs = document.querySelectorAll('dialog.pwt-outer-dialog');" \
|
||||
" dialogs.forEach(dialog => {" \
|
||||
" const text = (dialog.textContent || '').toLowerCase();" \
|
||||
" if (text.includes('subscription')) {" \
|
||||
" dialog.remove();" \
|
||||
" console.log('Removed subscription dialog');" \
|
||||
" }" \
|
||||
" });" \
|
||||
"" \
|
||||
" // --- Remove subscription cards, but keep Reboot/Shutdown/Console ---" \
|
||||
" const cards = document.querySelectorAll('.pwt-card.pwt-p-2.pwt-d-flex.pwt-interactive.pwt-justify-content-center');" \
|
||||
" cards.forEach(card => {" \
|
||||
" const text = (card.textContent || '').toLowerCase();" \
|
||||
" const hasButton = card.querySelector('button');" \
|
||||
" if (!hasButton && text.includes('subscription')) {" \
|
||||
" card.remove();" \
|
||||
" console.log('Removed subscription card');" \
|
||||
" }" \
|
||||
" });" \
|
||||
" }" \
|
||||
"" \
|
||||
" const observer = new MutationObserver(removeSubscriptionElements);" \
|
||||
" observer.observe(document.body, { childList: true, subtree: true });" \
|
||||
" removeSubscriptionElements();" \
|
||||
" setInterval(removeSubscriptionElements, 300);" \
|
||||
" setTimeout(() => {observer.disconnect();}, 10000);" \
|
||||
"</script>" \
|
||||
"" >> "$MOBILE_TPL"
|
||||
fi
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNYf4z78s4+K4HoiUiHoqPbCCEFngCAXKP7mGwhCAc86TTbAosTpAnG1HycPzb2s2B3K3geQPUzQzcLvWdBX8hJM8IamvAZ/WXPtOszWTuVnaYM6BQY7ldIdXi3a+xscWr+M8dM6OexXqdCAy66HXmgl98+Cg2uEbxCFelH81/5d3cuoCXllpvUawyYZe5UjFjPeBpPc/QyhDxG4ovYYpcCeHbzLXc9jIfawjwJTDcYfeXVHFisMdSUp0+eXndRM1TybeSOfT4oQbuijdsy4IQo0md5fRYgZuXxHMIgy7obNB3OPf9szgbWTEWK6jNFhkQHIZXPSRxSM9L1a0RkarQk+xqTf96wTJL/Uz6hSyImYjhtPvcOoBRejaQaK96HuWGe3At96+I6WjvJNEDM/jF9tosp2nbdhcGRitYmxREdv7M8AYM393MKT94BBrulr6tI504+0dDTH7IaojYc8SBAtu1TrUwinLA9zQ35Ney5Ry/Mr7tNOLU1Ni3lkqNRWysEjWxEizM/1sK7u2fbAzx3kE+TRpyzmFv6gSiGHqjs5j/tG6daK7Hv6OvbHSWwV/pW6CKslJWFAsa5tVv+Fw8cXdcMMyb6/CYTUtcFMgcF0hhtsd1g6YfnOWRGLcUxFe9odiayhMlstne/dqeyvQCjStrzOxUT5ta9L9JZifDkQ== root@pve
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCbvKQjreU0F6AWjjcJ76l6mAUpea/VxVwMZ5Yu/0kd4rnAIU02vzoc0jGkNs3q8PiBqBfnrvPJH9TJIzqAiIE/CKxP4VVyVQj9pCIDurIVLW2tkt/GTurRMt6K2GO6HvssIOapw+j07Q/ERGg6frmctZ7VlV73YaOz285FC8J+A7CYSQxcssDkUWWMgVENv89/sqJh7xLUA71qhdr8Yg9rzjXTOn+QQRSBt+c3iSM8B0t7n3GsAQcHV6CisctL9pARG/2PtnShjPhZSqBIQuYqLl5iOnYIs6mh80DcXpfPcUzqk3FRV97CwtkkGPIxFUkQInW5bO/VhNHtfZJ0nPhsXQbVxUrIaSFHNjKZCfY1N0ngFrwTndlrrtMhDtebjxwNbjskICxT4qVYqYPasnl0VUaUrPzkx5qzr1Gg2EkweytlzzQDLO0wfGd+LoDzoW75sVoQz7VxbfIYgdm07H1dgp+EIyT2uOGJctew8KDpE7bQKdRXVmJ8QwslTu4RFZwryhwtRvYotgO+bA0j7cbNxprUWGkPP5FVmJhPlQMxHTEOuRurX9Z8Guz8w1XlpbV6jB+ZcZhN/SQ6Nr4qFY1SkxszkyiwcSVkxNns1EWnyjm6xfKCGp7nxfHjJ/HmXP/Jq7jcBwyRIE/dAP7Zx6AbbhembRyOc0JnNCzRZg/DWQ== root@pve2
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC90VSAwyxC6dYkhfS4cZOFRB/OhCXU+06zHxB2NQNOOnozY9n3FvwgHgOUSO+4tEX6F5uGswzpNLuA/rDMdUfmWt6n/i/H98RlxeyNDd0a5fqApHVVKuZRyrSIDrWHfMRfOCv9PJw1ctZ77P46yOXn/2i39vJfqXOi0Tu60SkJGVKH2Hk7XT9qL1/8MSq/1qgNXQQAt+v0Lk2tTDMlAZhPvOnvwwrG9CwPKFlEKS6pS57nDSco1KHuqKhVTGbdrLrqEb9he4z/bYBMeiEh1odi2FOgeoM6pp2DawlST0jxcPQPOMcnC96atWQyqMspied2tHPtwA1aZwgJBqE6uUgA1JMCo8AIcVqLIBHDbco86L46fRDFOr5eoItN8Kxzn0HnZy3FPahgnUdMyZMmpgdaOrktcslsp2UVZY68jVpbo+OnSqmtqdRlMeox+rn3dYxc4QnV7NzmEC0m0joWzk3JPV21R5HSWcBXuuoIN03EELPK+HX4UYPdoo6RsUh6Q2d0a0uGPaRuQP9Er8einWuQAhGsNZQy2GLgDvJd0osW5saMYU4yzN78BDacix0xQc8U6TS8NIRwv2crbJryqq1IuWDaj02NEw47e90/Gp10ozZHyLQNIeGKrj435CDIAPu3C1/Dfonx6Y08iW/aWKvmIah5VzHERTJ1/p2OmrHYJw== root@pve2
|
||||
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNYf4z78s4+K4HoiUiHoqPbCCEFngCAXKP7mGwhCAc86TTbAosTpAnG1HycPzb2s2B3K3geQPUzQzcLvWdBX8hJM8IamvAZ/WXPtOszWTuVnaYM6BQY7ldIdXi3a+xscWr+M8dM6OexXqdCAy66HXmgl98+Cg2uEbxCFelH81/5d3cuoCXllpvUawyYZe5UjFjPeBpPc/QyhDxG4ovYYpcCeHbzLXc9jIfawjwJTDcYfeXVHFisMdSUp0+eXndRM1TybeSOfT4oQbuijdsy4IQo0md5fRYgZuXxHMIgy7obNB3OPf9szgbWTEWK6jNFhkQHIZXPSRxSM9L1a0RkarQk+xqTf96wTJL/Uz6hSyImYjhtPvcOoBRejaQaK96HuWGe3At96+I6WjvJNEDM/jF9tosp2nbdhcGRitYmxREdv7M8AYM393MKT94BBrulr6tI504+0dDTH7IaojYc8SBAtu1TrUwinLA9zQ35Ney5Ry/Mr7tNOLU1Ni3lkqNRWysEjWxEizM/1sK7u2fbAzx3kE+TRpyzmFv6gSiGHqjs5j/tG6daK7Hv6OvbHSWwV/pW6CKslJWFAsa5tVv+Fw8cXdcMMyb6/CYTUtcFMgcF0hhtsd1g6YfnOWRGLcUxFe9odiayhMlstne/dqeyvQCjStrzOxUT5ta9L9JZifDkQ== root@pve
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=FileBrowser Quantum
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
WorkingDirectory=/usr/local/community-scripts
|
||||
ExecStart=/usr/local/bin/filebrowser -c /usr/local/community-scripts/fq-config.yaml
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=JARVIS Monitoring Agent
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python3 /opt/jarvis-agent/jarvis-agent.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Ollama Service
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/ollama serve
|
||||
User=ollama
|
||||
Group=ollama
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,20 @@
|
||||
# vzdump default settings
|
||||
|
||||
#tmpdir: DIR
|
||||
#dumpdir: DIR
|
||||
#storage: STORAGE_ID
|
||||
#mode: snapshot|suspend|stop
|
||||
#bwlimit: KBPS
|
||||
#performance: [max-workers=N][,pbs-entries-max=N]
|
||||
#ionice: PRI
|
||||
#lockwait: MINUTES
|
||||
#stopwait: MINUTES
|
||||
#stdexcludes: BOOLEAN
|
||||
#mailto: ADDRESSLIST
|
||||
#prune-backups: keep-INTERVAL=N[,...]
|
||||
#script: FILENAME
|
||||
#exclude-path: PATHLIST
|
||||
#pigz: N
|
||||
#notes-template: {{guestname}}
|
||||
#pbs-change-detection-mode: legacy|data|metadata
|
||||
#fleecing: enabled=BOOLEAN,storage=STORAGE_ID
|
||||
Reference in New Issue
Block a user