Compare commits
107 commits
f78c2bdd41
...
ec26eb548f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ec26eb548f | ||
![]() |
17181f9df0 | ||
![]() |
3d8deecd68 | ||
![]() |
7f42679f29 | ||
![]() |
a9918735ea | ||
![]() |
ef192700ba | ||
![]() |
83149c197e | ||
![]() |
6fef63655c | ||
![]() |
63b68b8d3e | ||
![]() |
3b257aadab | ||
![]() |
88e80f4107 | ||
![]() |
8dfadbf9c3 | ||
![]() |
0cda286db1 | ||
![]() |
d8de90fa5d | ||
![]() |
e05d987036 | ||
![]() |
c8b7e34732 | ||
![]() |
bb6eeba6fb | ||
![]() |
6c2d4ca69f | ||
![]() |
706c4028f8 | ||
![]() |
3cd41adeaf | ||
![]() |
8a13421577 | ||
![]() |
9ff8dce802 | ||
![]() |
49081248ae | ||
![]() |
116697af9f | ||
![]() |
dc2dd9aa7a | ||
![]() |
495f5537be | ||
![]() |
0e28b18298 | ||
![]() |
8d4abe1ec6 | ||
![]() |
ee3625311b | ||
![]() |
1343a85e0b | ||
![]() |
fbe62c8127 | ||
![]() |
1387b5f1ae | ||
![]() |
e3a1438247 | ||
![]() |
b8cbf4648a | ||
![]() |
15f0317fbe | ||
![]() |
e44fc3dc04 | ||
![]() |
f72ee7c85b | ||
![]() |
5eac0e8c85 | ||
![]() |
fbee9a32df | ||
![]() |
1bde29bb17 | ||
![]() |
d10f2b1eb3 | ||
![]() |
1397e9c9a3 | ||
![]() |
1b84e84841 | ||
![]() |
c37be21034 | ||
![]() |
57079a0cbe | ||
![]() |
cd5b854b00 | ||
![]() |
04d55caef6 | ||
![]() |
8285a12f00 | ||
![]() |
9946edc6f3 | ||
![]() |
a3c7acc399 | ||
![]() |
4530a34175 | ||
![]() |
b8100f472b | ||
![]() |
9b104cac25 | ||
![]() |
7243ad9e9b | ||
![]() |
12268daad6 | ||
![]() |
d4738d762b | ||
![]() |
72f560809b | ||
![]() |
f55d46281c | ||
![]() |
59537a536f | ||
![]() |
ab55ad1020 | ||
![]() |
bb3b4b9bca | ||
![]() |
f31f86aa21 | ||
![]() |
30b3d570fb | ||
![]() |
f6baeb328b | ||
![]() |
31a4da75aa | ||
![]() |
a51d62f5d2 | ||
![]() |
bada714b10 | ||
![]() |
6f9218c5a1 | ||
![]() |
e6940b151c | ||
![]() |
5647654135 | ||
![]() |
5fd9452a6c | ||
![]() |
2a84822cfe | ||
![]() |
e62a7781b4 | ||
![]() |
9f4e304aec | ||
![]() |
8b2d8d974e | ||
![]() |
3cddebee11 | ||
![]() |
c8b9a46aad | ||
![]() |
35d8d4828b | ||
![]() |
b9ff7e5953 | ||
![]() |
8063833950 | ||
![]() |
34b42832ac | ||
![]() |
52404fe7ce | ||
![]() |
76a568e8b6 | ||
![]() |
6706d04298 | ||
![]() |
cf09493486 | ||
![]() |
8cabb029b3 | ||
![]() |
e81f28cf04 | ||
![]() |
df4ffd2d77 | ||
![]() |
b235ede36d | ||
![]() |
e5a16b5506 | ||
![]() |
5e5118215a | ||
![]() |
452c983f63 | ||
![]() |
c9e565bbde | ||
![]() |
5ed8f08231 | ||
![]() |
7588741b30 | ||
![]() |
f416852225 | ||
![]() |
f5ab497bff | ||
![]() |
f2439dcf66 | ||
![]() |
b27f07a867 | ||
![]() |
824b10546d | ||
![]() |
33d973927c | ||
![]() |
b528e9b94b | ||
![]() |
8a6c166f16 | ||
![]() |
49346ba20b | ||
![]() |
31bf80f771 | ||
![]() |
1340aaf52e | ||
![]() |
739c38d1b4 |
85 changed files with 1413 additions and 468 deletions
22
.editorconfig
Normal file
22
.editorconfig
Normal file
|
@ -0,0 +1,22 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.toml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.yaml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
4
.envrc
4
.envrc
|
@ -2,7 +2,11 @@
|
|||
|
||||
python3 -m venv .venv
|
||||
source ./.venv/bin/activate
|
||||
PATH_add .venv/bin
|
||||
PATH_add bin
|
||||
python3 -m pip install --upgrade pip
|
||||
|
||||
rm -rf .cache/bw/git_deploy
|
||||
export BW_GIT_DEPLOY_CACHE=.cache/bw/git_deploy
|
||||
export EXPERIMENTAL_UPLOAD_VIA_CAT=1
|
||||
mkdir -p "$BW_GIT_DEPLOY_CACHE"
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
.secrets.cfg*
|
||||
.venv
|
||||
.cache
|
||||
*.pyc
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
3.9.0
|
23
README.md
23
README.md
|
@ -12,3 +12,26 @@ Raspberry pi as soundcard
|
|||
- gadget mode
|
||||
- OTG g_audio
|
||||
- https://audiosciencereview.com/forum/index.php?threads/raspberry-pi-as-usb-to-i2s-adapter.8567/post-215824
|
||||
|
||||
# install bw fork
|
||||
|
||||
pip3 install --editable git+file:///Users/mwiegand/Projekte/bundlewrap-fork#egg=bundlewrap
|
||||
|
||||
# monitor timers
|
||||
|
||||
```sh
|
||||
Timer=backup
|
||||
|
||||
Triggers=$(systemctl show ${Timer}.timer --property=Triggers --value)
|
||||
echo $Triggers
|
||||
if systemctl is-failed "$Triggers"
|
||||
then
|
||||
InvocationID=$(systemctl show "$Triggers" --property=InvocationID --value)
|
||||
echo $InvocationID
|
||||
ExitCode=$(systemctl show "$Triggers" -p ExecStartEx --value | sed 's/^{//' | sed 's/}$//' | tr ';' '\n' | xargs -n 1 | grep '^status=' | cut -d '=' -f 2)
|
||||
echo $ExitCode
|
||||
journalctl INVOCATION_ID="$InvocationID" --output cat
|
||||
fi
|
||||
```
|
||||
|
||||
telegraf: execd for daemons
|
||||
|
|
|
@ -7,9 +7,10 @@ from ipaddress import ip_interface
|
|||
repo = Repository(dirname(dirname(realpath(__file__))))
|
||||
nodes = [
|
||||
node
|
||||
for node in repo.nodes_in_group('debian')
|
||||
for node in sorted(repo.nodes_in_group('debian'))
|
||||
if not node.dummy
|
||||
]
|
||||
reboot_nodes = []
|
||||
|
||||
print('updating nodes:', sorted(node.name for node in nodes))
|
||||
|
||||
|
@ -21,13 +22,16 @@ for node in nodes:
|
|||
print('--------------------------------------')
|
||||
repo.libs.wol.wake(node)
|
||||
print(node.run('DEBIAN_FRONTEND=noninteractive apt update').stdout.decode())
|
||||
print(node.run('DEBIAN_FRONTEND=noninteractive apt -y dist-upgrade').stdout.decode())
|
||||
print(node.run('DEBIAN_FRONTEND=noninteractive apt list --upgradable').stdout.decode())
|
||||
if int(node.run('DEBIAN_FRONTEND=noninteractive apt list --upgradable 2> /dev/null | grep upgradable | wc -l').stdout.decode()):
|
||||
print(node.run('DEBIAN_FRONTEND=noninteractive apt -y dist-upgrade').stdout.decode())
|
||||
reboot_nodes.append(node)
|
||||
|
||||
# REBOOT IN ORDER
|
||||
|
||||
wireguard_servers = [
|
||||
node
|
||||
for node in nodes
|
||||
for node in reboot_nodes
|
||||
if node.has_bundle('wireguard')
|
||||
and (
|
||||
ip_interface(node.metadata.get('wireguard/my_ip')).network.prefixlen <
|
||||
|
@ -37,7 +41,7 @@ wireguard_servers = [
|
|||
|
||||
wireguard_s2s = [
|
||||
node
|
||||
for node in nodes
|
||||
for node in reboot_nodes
|
||||
if node.has_bundle('wireguard')
|
||||
and (
|
||||
ip_interface(node.metadata.get('wireguard/my_ip')).network.prefixlen ==
|
||||
|
@ -47,12 +51,11 @@ wireguard_s2s = [
|
|||
|
||||
everything_else = [
|
||||
node
|
||||
for node in nodes
|
||||
for node in reboot_nodes
|
||||
if not node.has_bundle('wireguard')
|
||||
]
|
||||
|
||||
print('======================================')
|
||||
print(len(everything_else), len(wireguard_s2s), len(wireguard_servers))
|
||||
|
||||
for node in [
|
||||
*everything_else,
|
||||
|
@ -60,4 +63,7 @@ for node in [
|
|||
*wireguard_servers,
|
||||
]:
|
||||
print('rebooting', node.name)
|
||||
print(node.run('systemctl reboot').stdout.decode())
|
||||
try:
|
||||
print(node.run('systemctl reboot').stdout.decode())
|
||||
except Exception as e:
|
||||
print(e)
|
9
bin/wake
Executable file
9
bin/wake
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from bundlewrap.repo import Repository
|
||||
from os.path import realpath, dirname
|
||||
from sys import argv
|
||||
|
||||
repo = Repository(dirname(dirname(realpath(__file__))))
|
||||
|
||||
repo.libs.wol.wake(repo.get_node(argv[1]))
|
|
@ -21,7 +21,9 @@ for peer in server_node.metadata.get('wireguard/s2s').values():
|
|||
allowed_ips.append(ip_network(network))
|
||||
|
||||
conf = \
|
||||
f'''[Interface]
|
||||
f'''>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
[Interface]
|
||||
PrivateKey = {repo.libs.wireguard.privkey(data['peer_id'])}
|
||||
ListenPort = 51820
|
||||
Address = {data['peer_ip']}
|
||||
|
@ -32,10 +34,12 @@ PublicKey = {repo.libs.wireguard.pubkey(server_node.metadata.get('id'))}
|
|||
PresharedKey = {repo.libs.wireguard.psk(data['peer_id'], server_node.metadata.get('id'))}
|
||||
AllowedIPs = {', '.join(str(client_route) for client_route in sorted(allowed_ips))}
|
||||
Endpoint = {ip_interface(server_node.metadata.get('network/external/ipv4')).ip}:51820
|
||||
PersistentKeepalive = 10'''
|
||||
PersistentKeepalive = 10
|
||||
|
||||
if input("as test or qrcode? [Tq]: ") in 'Qq':
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'''
|
||||
|
||||
print(conf)
|
||||
|
||||
if input("print qrcode? [yN]: ").upper() == 'Y':
|
||||
import pyqrcode
|
||||
print(pyqrcode.create(conf).terminal(quiet_zone=1))
|
||||
else:
|
||||
print(conf)
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
date=$(date --utc +%s%N)
|
||||
|
||||
for metric in TIMELEFT LOADPCT BCHARGE
|
||||
METRICS=$(apcaccess)
|
||||
|
||||
for METRIC in TIMELEFT LOADPCT BCHARGE
|
||||
do
|
||||
echo "apcupsd $metric=$(apcaccess -p $metric | cut -d' ' -f1) $date"
|
||||
echo "apcupsd $METRIC=$(grep $METRIC <<< $METRICS | cut -d ':' -f 2 | xargs | cut -d ' ' -f 1 ) $date"
|
||||
done
|
||||
|
|
|
@ -20,6 +20,8 @@ defaults = {
|
|||
'commands': ["sudo /usr/local/share/telegraf/apcupsd"],
|
||||
'name_override': "apcupsd",
|
||||
'data_format': "influx",
|
||||
'interval': '30s',
|
||||
'flush_interval': '30s',
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -48,8 +48,8 @@ hosts = {}
|
|||
for source_string in node.metadata.get('apt/sources'):
|
||||
source = repo.libs.apt.AptSource(source_string)
|
||||
hosts\
|
||||
.setdefault(source.url.hostname, set())\
|
||||
.add(source)
|
||||
.setdefault(source.url.hostname, list())\
|
||||
.append(source)
|
||||
|
||||
# create sources lists and keyfiles
|
||||
|
||||
|
@ -61,12 +61,13 @@ for host, sources in hosts.items():
|
|||
source.options['signed-by'] = [destination_path]
|
||||
|
||||
files[f'/etc/apt/sources.list.d/{host}.list'] = {
|
||||
'content': '\n'.join(
|
||||
str(source) for source in sorted(sources)
|
||||
).format(
|
||||
release=node.metadata.get('os_release'),
|
||||
version=node.os_version[0], # WIP crystal
|
||||
),
|
||||
'content': '\n'.join(sorted(set(
|
||||
str(source).format(
|
||||
release=node.metadata.get('os_release'),
|
||||
version=node.os_version[0], # WIP crystal
|
||||
)
|
||||
for source in sources
|
||||
))),
|
||||
'triggers': {
|
||||
'action:apt_update',
|
||||
},
|
||||
|
|
|
@ -33,7 +33,7 @@ zfs snap "$source_dataset@$new_bookmark"
|
|||
if zfs list -t bookmark -H -o name | grep "^$source_dataset#$bookmark_prefix" | wc -l | grep -q "^0$"
|
||||
then
|
||||
echo "INITIAL BACKUP"
|
||||
# do in subshell, otherwise ctr+c will lead to 0 exitcode
|
||||
# do in subshell, otherwise ctr+c will lead to 0 exitcode
|
||||
$(zfs send -v "$source_dataset@$new_bookmark" | $ssh sudo zfs recv -F "$target_dataset")
|
||||
else
|
||||
echo "INCREMENTAL BACKUP"
|
||||
|
@ -44,8 +44,21 @@ fi
|
|||
|
||||
if [[ "$?" == "0" ]]
|
||||
then
|
||||
|
||||
# delete old local bookmarks
|
||||
for destroyable_bookmark in $(zfs list -t bookmark -H -o name "$dataset" | grep "^$dataset#$bookmark_prefix")
|
||||
do
|
||||
zfs destroy "$destroyable_bookmark"
|
||||
done
|
||||
|
||||
# delete snapshots from bookmarks (except newest, even of not necessary; maybe for resuming tho)
|
||||
for destroyable_snapshot in $($ssh sudo zfs list -t snapshot -H -o name "$dataset" | grep "^$dataset@$bookmark_prefix" | grep -v "$new_bookmark")
|
||||
do
|
||||
$ssh sudo zfs destroy "$destroyable_snapshot"
|
||||
done
|
||||
|
||||
zfs bookmark "$source_dataset@$new_bookmark" "$source_dataset#$new_bookmark"
|
||||
#zfs destroy "$source_dataset@$new_bookmark" # keep snapshots?
|
||||
zfs destroy "$source_dataset@$new_bookmark" # keep snapshots?
|
||||
echo "SUCCESS"
|
||||
else
|
||||
zfs destroy "$source_dataset@$new_bookmark"
|
||||
|
|
|
@ -114,6 +114,6 @@ for name, conf in node.metadata.get('flask').items():
|
|||
svc_systemd[name] = {
|
||||
'needs': [
|
||||
f'action:flask_{name}_pip_install',
|
||||
f'file:/etc/systemd/system/{name}.service',
|
||||
f'file:/usr/local/lib/systemd/system/{name}.service',
|
||||
],
|
||||
}
|
||||
|
|
|
@ -11,10 +11,6 @@ downloads['/usr/local/bin/gitea'] = {
|
|||
},
|
||||
}
|
||||
|
||||
users['git'] = {
|
||||
'home': '/home/git',
|
||||
}
|
||||
|
||||
directories['/var/lib/gitea'] = {
|
||||
'owner': 'git',
|
||||
'mode': '0700',
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
database_password = repo.vault.password_for(f'{node.name} postgresql gitea')
|
||||
|
||||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'git': {
|
||||
'needed_by': {
|
||||
'svc_systemd:gitea',
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'gitea': {
|
||||
'database': {
|
||||
'host': 'localhost',
|
||||
|
@ -52,16 +61,32 @@ defaults = {
|
|||
},
|
||||
},
|
||||
},
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
'tank/gitea': {
|
||||
'mountpoint': '/var/lib/gitea',
|
||||
},
|
||||
'users': {
|
||||
'git': {
|
||||
'home': '/home/git',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'zfs/datasets',
|
||||
)
|
||||
def zfs(metadata):
|
||||
if not node.has_bundle('zfs'):
|
||||
return {}
|
||||
|
||||
return {
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
f"{metadata.get('zfs/storage_classes/ssd')}/gitea": {
|
||||
'mountpoint': '/var/lib/gitea',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nginx/vhosts',
|
||||
)
|
||||
|
|
|
@ -101,11 +101,11 @@ for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
|
|||
dashboard['title'] = monitored_node.name
|
||||
dashboard['uid'] = monitored_node.metadata.get('id')
|
||||
panel_id = count(start=1)
|
||||
|
||||
|
||||
for row_id, row_name in enumerate(sorted(monitored_node.metadata.get('grafana_rows')), start=1):
|
||||
with open(repo.path.join([f'data/grafana/rows/{row_name}.py'])) as file:
|
||||
row = eval(file.read())
|
||||
|
||||
|
||||
for panel_in_row, (panel_name, panel_config) in enumerate(row.items()):
|
||||
panel = deepcopy(panel_template)
|
||||
panel['id'] = next(panel_id)
|
||||
|
@ -113,7 +113,7 @@ for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
|
|||
panel['gridPos']['w'] = 24 // len(row)
|
||||
panel['gridPos']['x'] = (24 // len(row)) * panel_in_row
|
||||
panel['gridPos']['y'] = (row_id - 1) * panel['gridPos']['h']
|
||||
|
||||
|
||||
if 'display_name' in panel_config:
|
||||
panel['fieldConfig']['defaults']['displayName'] = '${'+panel_config['display_name']+'}'
|
||||
|
||||
|
@ -127,13 +127,17 @@ for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
|
|||
panel['fieldConfig']['defaults']['min'] = panel_config['min']
|
||||
if 'max' in panel_config:
|
||||
panel['fieldConfig']['defaults']['max'] = panel_config['max']
|
||||
if 'soft_max' in panel_config:
|
||||
panel['fieldConfig']['defaults']['custom']['axisSoftMax'] = panel_config['soft_max']
|
||||
|
||||
if 'legend' in panel_config:
|
||||
panel['options']['legend'].update(panel_config['legend'])
|
||||
|
||||
if 'tooltip' in panel_config:
|
||||
panel['options']['tooltip']['mode'] = panel_config['tooltip']
|
||||
|
||||
if panel_config['tooltip'] == 'multi':
|
||||
panel['options']['tooltip']['sort'] = 'desc'
|
||||
|
||||
for query_name, query_config in panel_config['queries'].items():
|
||||
panel['targets'].append({
|
||||
'refId': query_name,
|
||||
|
@ -142,22 +146,22 @@ for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
|
|||
host=monitored_node.name,
|
||||
negative=query_config.get('negative', False),
|
||||
boolean_to_int=query_config.get('boolean_to_int', False),
|
||||
resolution=query_config.get('resolution', 1) * 4,
|
||||
minimum=query_config.get('minimum', None),
|
||||
filters={
|
||||
'host': monitored_node.name,
|
||||
**query_config['filters'],
|
||||
},
|
||||
exists=query_config.get('exists', []),
|
||||
function=query_config.get('function', None),
|
||||
).strip()
|
||||
})
|
||||
|
||||
|
||||
dashboard['panels'].append(panel)
|
||||
|
||||
|
||||
files[f'/var/lib/grafana/dashboards/{monitored_node.name}.json'] = {
|
||||
'content': json.dumps(dashboard, indent=4),
|
||||
'triggers': [
|
||||
'svc_systemd:grafana-server:restart',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,20 @@ defaults = {
|
|||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'grafana/config/server/domain',
|
||||
)
|
||||
def domain(metadata):
|
||||
return {
|
||||
'grafana': {
|
||||
'config': {
|
||||
'server': {
|
||||
'domain': metadata.get('grafana/hostname'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'grafana/datasources',
|
||||
)
|
||||
|
@ -115,10 +129,7 @@ def nginx(metadata):
|
|||
'nginx': {
|
||||
'vhosts': {
|
||||
metadata.get('grafana/hostname'): {
|
||||
'content': 'nginx/proxy_pass.conf',
|
||||
'context': {
|
||||
'target': 'http://127.0.0.1:8300',
|
||||
}
|
||||
'content': 'grafana/vhost.conf',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
5
bundles/grub/files/grub
Normal file
5
bundles/grub/files/grub
Normal file
|
@ -0,0 +1,5 @@
|
|||
GRUB_DEFAULT=0
|
||||
GRUB_TIMEOUT=1
|
||||
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="${' '.join(kernel_params)}"
|
||||
GRUB_CMDLINE_LINUX=""
|
20
bundles/grub/items.py
Normal file
20
bundles/grub/items.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
files = {
|
||||
'/etc/default/grub': {
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'timeout': node.metadata.get('grub/timeout'),
|
||||
'kernel_params': node.metadata.get('grub/kernel_params'),
|
||||
},
|
||||
'mode': '0644',
|
||||
'triggers': {
|
||||
'action:update-grub',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
actions = {
|
||||
'update-grub': {
|
||||
'command': 'update-grub',
|
||||
'triggered': True,
|
||||
},
|
||||
}
|
6
bundles/grub/metadata.py
Normal file
6
bundles/grub/metadata.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
defaults = {
|
||||
'grub': {
|
||||
'timeout': 1,
|
||||
'kernel_params': set(),
|
||||
},
|
||||
}
|
|
@ -2,6 +2,7 @@ defaults = {
|
|||
'apt': {
|
||||
'packages': {
|
||||
'lm-sensors': {},
|
||||
'console-data': {}, # leykeys de
|
||||
},
|
||||
},
|
||||
'grafana_rows': {
|
||||
|
|
39
bundles/htop/files/htoprc.global
Normal file
39
bundles/htop/files/htoprc.global
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
||||
# The parser is also very primitive, and not human-friendly.
|
||||
fields=0 48 17 18 38 39 40 2 46 47 109 110 49 1
|
||||
sort_key=46
|
||||
sort_direction=-1
|
||||
tree_sort_key=0
|
||||
tree_sort_direction=1
|
||||
hide_kernel_threads=0
|
||||
hide_userland_threads=0
|
||||
shadow_other_users=0
|
||||
show_thread_names=0
|
||||
show_program_path=1
|
||||
highlight_base_name=0
|
||||
highlight_megabytes=1
|
||||
highlight_threads=1
|
||||
highlight_changes=0
|
||||
highlight_changes_delay_secs=5
|
||||
find_comm_in_cmdline=1
|
||||
strip_exe_from_cmdline=1
|
||||
show_merged_command=0
|
||||
tree_view=0
|
||||
tree_view_always_by_pid=0
|
||||
header_margin=1
|
||||
detailed_cpu_time=0
|
||||
cpu_count_from_one=1
|
||||
show_cpu_usage=0
|
||||
show_cpu_frequency=0
|
||||
show_cpu_temperature=0
|
||||
degree_fahrenheit=0
|
||||
update_process_names=0
|
||||
account_guest_in_cpu_meter=0
|
||||
color_scheme=0
|
||||
enable_mouse=1
|
||||
delay=20
|
||||
left_meters=Hostname Tasks DiskIO NetworkIO Blank CPU Memory Swap Blank LeftCPUs${cpus_per_row}
|
||||
left_meter_modes=2 2 2 2 2 1 1 1 2 1
|
||||
right_meters=CPU Blank PressureStallCPUSome PressureStallMemorySome PressureStallIOSome Blank RightCPUs${cpus_per_row}
|
||||
right_meter_modes=3 2 1 1 1 2 1
|
||||
hide_function_bar=0
|
8
bundles/htop/items.py
Normal file
8
bundles/htop/items.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
files = {
|
||||
'/etc/htoprc.global': {
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'cpus_per_row': 4 if node.metadata.get('vm/threads', node.metadata.get('vm/cores', 1)) > 8 else 2,
|
||||
},
|
||||
},
|
||||
}
|
7
bundles/htop/metadata.py
Normal file
7
bundles/htop/metadata.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'htop': {},
|
||||
},
|
||||
},
|
||||
}
|
|
@ -5,7 +5,7 @@ directories['/var/lib/influxdb'] = {
|
|||
'owner': 'influxdb',
|
||||
'group': 'influxdb',
|
||||
'needs': [
|
||||
'zfs_dataset:tank/influxdb',
|
||||
f"zfs_dataset:{node.metadata.get('zfs/storage_classes/ssd')}/influxdb",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ defaults = {
|
|||
'apt': {
|
||||
'packages': {
|
||||
'influxdb2': {},
|
||||
'influxdb2-cli': {},
|
||||
},
|
||||
'sources': {
|
||||
'deb https://repos.influxdata.com/debian {release} stable',
|
||||
|
@ -21,15 +22,6 @@ defaults = {
|
|||
'http-bind-address': ':8200',
|
||||
},
|
||||
},
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
'tank/influxdb': {
|
||||
'mountpoint': '/var/lib/influxdb',
|
||||
'recordsize': '8192',
|
||||
'atime': 'off',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@metadata_reactor.provides(
|
||||
|
@ -45,6 +37,26 @@ def admin_password(metadata):
|
|||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'zfs/datasets',
|
||||
)
|
||||
def zfs(metadata):
|
||||
if not node.has_bundle('zfs'):
|
||||
return {}
|
||||
|
||||
return {
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
f"{metadata.get('zfs/storage_classes/ssd')}/influxdb": {
|
||||
'mountpoint': '/var/lib/influxdb',
|
||||
'recordsize': '8192',
|
||||
'atime': 'off',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'dns',
|
||||
)
|
||||
|
|
|
@ -6,6 +6,7 @@ defaults = {
|
|||
'version': {
|
||||
10: 11,
|
||||
11: 17,
|
||||
12: 17,
|
||||
}[node.os_version[0]],
|
||||
},
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ for name, config in node.metadata.get('left4dead2/servers').items():
|
|||
}
|
||||
svc_systemd[f'left4dead2-server-{name}'] = {
|
||||
'needs': [
|
||||
f'file:/etc/systemd/system/left4dead2-server-{name}.service',
|
||||
f'file:/usr/local/lib/systemd/system/left4dead2-server-{name}.service',
|
||||
],
|
||||
}
|
||||
server_units.add(f'left4dead2-server-{name}')
|
||||
|
@ -87,7 +87,7 @@ for id in node.metadata.get('left4dead2/workshop'):
|
|||
# TIDYUP
|
||||
|
||||
find_obsolete_units = (
|
||||
'find /etc/systemd/system -type f -name "left4dead2-server-*.service" ' +
|
||||
'find /usr/local/lib/systemd/system -type f -name "left4dead2-server-*.service" ' +
|
||||
' '.join(f"! -name '{name}.service'" for name in server_units)
|
||||
)
|
||||
actions['remove_obsolete_left4dead2_units'] = {
|
||||
|
|
|
@ -10,6 +10,9 @@ files = {
|
|||
'content': '\n'.join(
|
||||
f'{locale} {type}' for locale, type in installed_locales
|
||||
),
|
||||
'needs': {
|
||||
'pkg_apt:locales',
|
||||
},
|
||||
'triggers': {
|
||||
'action:locale-gen',
|
||||
},
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
USER="$1"
|
||||
SOURCEPATH="/var/lib/nextcloud/$1/files/$2"
|
||||
|
||||
REL_SOURCE_PATH="/$1/files/$2"
|
||||
ABS_SOURCE_PATH="/var/lib/nextcloud/$1/files/$2"
|
||||
|
||||
REL_DEST_PATH="/$1/files/$3"
|
||||
ABS_DEST_PATH="/var/lib/nextcloud/$1/files/$3"
|
||||
|
@ -11,52 +13,63 @@ ABS_UNSORTABLE_PATH="/var/lib/nextcloud/$1/files/$4"
|
|||
|
||||
echo "STARTING..."
|
||||
|
||||
chown -R www-data:www-data "$SOURCEPATH"
|
||||
chmod -R 770 "$SOURCEPATH"
|
||||
chown -R www-data:www-data "$ABS_SOURCE_PATH"
|
||||
chmod -R 770 "$ABS_SOURCE_PATH"
|
||||
|
||||
SCAN="FALSE"
|
||||
IFS=$'\n'
|
||||
for f in `find "$SOURCEPATH" -iname *.PNG -o -iname *.JPG -o -iname *.CR2 -o -iname *.CR3 -o -iname *.MP4 -o -iname *.MOV`; do
|
||||
for f in `find "$ABS_SOURCE_PATH" -iname *.PNG -o -iname *.JPG -o -iname *.JPEG -o -iname *.HEIC -o -iname *.CR2 -o -iname *.CR3 -o -iname *.MP4 -o -iname *.MOV`; do
|
||||
SCAN="TRUE"
|
||||
echo "PROCESSING: $f"
|
||||
DATE=`exiftool "$f" | grep -m 1 "Create Date"`
|
||||
if ! echo "$DATE" | grep "Create Date" >/dev/null
|
||||
|
||||
EXIF=`exiftool "$f"`
|
||||
if grep -q '^Create Date' <<< $EXIF
|
||||
then
|
||||
RELPATH=$(realpath --relative-to="$SOURCEPATH" "$f")
|
||||
DATETIME=`grep -m 1 "^Create Date" <<< $EXIF | cut -d: -f2- | xargs`
|
||||
elif grep -q '^File Modification Date' <<< $EXIF
|
||||
then
|
||||
DATETIME=`grep -m 1 '^File Modification Date' <<< $EXIF | cut -d: -f2- | xargs`
|
||||
else
|
||||
RELPATH=$(realpath --relative-to="$ABS_SOURCE_PATH" "$f")
|
||||
DIRNAME=$(dirname "$ABS_UNSORTABLE_PATH/$RELPATH")
|
||||
echo "UNSORTABLE: $f"
|
||||
mkdir -p "$DIRNAME"
|
||||
mv "$f" "$DIRNAME"
|
||||
else
|
||||
YEAR=`echo $DATE | cut -d':' -f2 | cut -c 2-`
|
||||
MONTH=`echo $DATE | cut -d':' -f3`
|
||||
DAY=`echo $DATE | cut -d':' -f4 | cut -d' ' -f1`
|
||||
HOUR=`echo $DATE | cut -d':' -f4 | cut -d' ' -f2`
|
||||
MINUTE=`echo $DATE | cut -d':' -f5`
|
||||
SECOND=`echo $DATE | cut -d':' -f6`
|
||||
SECOND=`echo $SECOND | cut -d'+' -f1` # remove timezone
|
||||
HASH=`sha256sum "$f" | xxd -r -p | base64 | head -c 3 | tr '/+' '_-'`
|
||||
EXT=`echo "${f##*.}" | tr '[:upper:]' '[:lower:]'`
|
||||
if [[ "$EXT" = "cr2" ]] || [[ "$EXT" = "cr3" ]]
|
||||
then
|
||||
RAW="raw/"
|
||||
else
|
||||
RAW=""
|
||||
fi
|
||||
FILE="$ABS_DEST_PATH/$YEAR-$MONTH/$RAW$YEAR$MONTH$DAY"-"$HOUR$MINUTE$SECOND"_"$HASH"."$EXT"
|
||||
echo "DESTINATION: $FILE"
|
||||
mkdir -p "$(dirname "$FILE")"
|
||||
mv -v "$f" "$FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
DATE=`cut -d' ' -f1 <<< $DATETIME`
|
||||
TIME=`cut -d' ' -f2 <<< $DATETIME | cut -d'+' -f1`
|
||||
|
||||
YEAR=`cut -d':' -f1 <<< $DATE`
|
||||
MONTH=`cut -d':' -f2 <<< $DATE`
|
||||
DAY=`cut -d':' -f3 <<< $DATE`
|
||||
HOUR=`cut -d':' -f1 <<< $TIME`
|
||||
MINUTE=`cut -d':' -f2 <<< $TIME`
|
||||
SECOND=`cut -d':' -f3 <<< $TIME`
|
||||
|
||||
HASH=`sha256sum "$f" | xxd -r -p | base64 | head -c 3 | tr '/+' '_-'`
|
||||
EXT=`echo "${f##*.}" | tr '[:upper:]' '[:lower:]'`
|
||||
if [[ "$EXT" = "cr2" ]] || [[ "$EXT" = "cr3" ]]
|
||||
then
|
||||
RAW="raw/"
|
||||
else
|
||||
RAW=""
|
||||
fi
|
||||
FILE="$ABS_DEST_PATH/$YEAR-$MONTH/$RAW$YEAR$MONTH$DAY"-"$HOUR$MINUTE$SECOND"_"$HASH"."$EXT"
|
||||
echo "DESTINATION: $FILE"
|
||||
mkdir -p "$(dirname "$FILE")"
|
||||
mv -v "$f" "$FILE"
|
||||
done
|
||||
|
||||
if [ "$SCAN" == "TRUE" ]; then
|
||||
echo "SCANNING..."
|
||||
# find "$SOURCEPATH/"* -type d -empty -delete >> /var/echo/nc-picsort.echo # nextcloud app bug when deleting folders
|
||||
# find "$ABS_SOURCE_PATH/"* -type d -empty -delete >> /var/echo/nc-picsort.echo # nextcloud app bug when deleting folders
|
||||
chown -R www-data:www-data "$ABS_DEST_PATH"
|
||||
chown -R www-data:www-data "$ABS_UNSORTABLE_PATH"
|
||||
chmod -R 770 "$ABS_DEST_PATH"
|
||||
chmod -R 770 "$ABS_UNSORTABLE_PATH"
|
||||
sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_SOURCE_PATH"
|
||||
sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_UNSORTABLE_PATH"
|
||||
sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_DEST_PATH"
|
||||
sudo -u www-data php /opt/nextcloud/occ preview:pre-generate
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
from shlex import quote as q
|
||||
|
||||
|
||||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'libimage-exiftool-perl': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd-timers',
|
||||
)
|
||||
|
|
|
@ -28,4 +28,15 @@ $CONFIG = array (
|
|||
"redis" => [
|
||||
"host" => "/var/run/redis/nextcloud.sock",
|
||||
],
|
||||
'trusted_domains' =>
|
||||
array (
|
||||
0 => 'localhost',
|
||||
1 => '127.0.0.1',
|
||||
2 => '${hostname}',
|
||||
),
|
||||
"log_type" => "syslog",
|
||||
"syslog_tag" => "nextcloud",
|
||||
"logfile" => "",
|
||||
"loglevel" => 3,
|
||||
"default_phone_region" => "DE",
|
||||
);
|
||||
|
|
|
@ -75,6 +75,7 @@ files = {
|
|||
'mode': '640',
|
||||
'context': {
|
||||
'db_password': node.metadata.get('postgresql/roles/nextcloud/password'),
|
||||
'hostname': node.metadata.get('nextcloud/hostname'),
|
||||
},
|
||||
'needs': [
|
||||
'directory:/etc/nextcloud',
|
||||
|
@ -126,7 +127,7 @@ files['/opt/nextcloud_upgrade_status.php'] = {
|
|||
|
||||
actions['upgrade_nextcloud'] = {
|
||||
'command': repo.libs.nextcloud.occ('upgrade'),
|
||||
'unless': 'sudo -u www-data php /opt/nextcloud/upgrade_status.php; test $? -ne 99',
|
||||
'unless': 'sudo -u www-data php /opt/nextcloud_upgrade_status.php; test $? -ne 99',
|
||||
'needs': [
|
||||
'file:/opt/nextcloud_upgrade_status.php',
|
||||
'action:install_nextcloud',
|
||||
|
|
|
@ -5,6 +5,7 @@ defaults = {
|
|||
'apt': {
|
||||
'packages': {
|
||||
'php': {},
|
||||
'php-redis': {},
|
||||
'php-fpm': {},
|
||||
'php-curl': {},
|
||||
'php-gd': {},
|
||||
|
@ -15,6 +16,15 @@ defaults = {
|
|||
'php-cgi': {},
|
||||
'php-zip': {},
|
||||
'php-pgsql': {},
|
||||
'php-bz2': {}, # face recognition
|
||||
'php-intl': {},
|
||||
'php-imagick': {},
|
||||
'libmagickcore-6.q16-6-extra': {},
|
||||
'php-gmp': {},
|
||||
'php-bcmath': {},
|
||||
},
|
||||
'sources': {
|
||||
'deb https://repo.delellis.com.ar {release} {release}', # face recognition
|
||||
},
|
||||
},
|
||||
'archive': {
|
||||
|
@ -50,6 +60,11 @@ defaults = {
|
|||
'env[TMPDIR]': '/tmp',
|
||||
'env[TEMP]': '/tmp',
|
||||
},
|
||||
'php.ini': {
|
||||
'PHP': {
|
||||
'memory_limit': '3G', # face recognition requires 2G
|
||||
},
|
||||
},
|
||||
},
|
||||
'postgresql': {
|
||||
'roles': {
|
||||
|
@ -77,6 +92,11 @@ defaults = {
|
|||
'when': 'Sun 00:00:00',
|
||||
'user': 'www-data',
|
||||
},
|
||||
'nextcloud-face-recognition': {
|
||||
'command': '/usr/bin/php -f /opt/nextcloud/occ face:background_job -t 1800',
|
||||
'when': '*:0/10',
|
||||
'user': 'www-data',
|
||||
},
|
||||
},
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
|
@ -107,3 +127,16 @@ def vhost(metadata):
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nginx/vhosts'
|
||||
)
|
||||
def pdlib(metadata):
|
||||
return {
|
||||
'apt': {
|
||||
'packages': {
|
||||
f"php{metadata.get('php/version')}-pdlib": {}, # face recognition
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
[PHP]
|
||||
; Only needed for libapache2-mod-php?
|
||||
engine = On
|
||||
short_open_tag = Off
|
||||
precision = 14
|
||||
output_buffering = 4096
|
||||
zlib.output_compression = Off
|
||||
implicit_flush = Off
|
||||
serialize_precision = -1
|
||||
ignore_user_abort = Off
|
||||
zend.enable_gc = On
|
||||
expose_php = Off
|
||||
|
||||
max_execution_time = 300
|
||||
max_input_time = 600
|
||||
memory_limit = 1G
|
||||
|
||||
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
|
||||
display_startup_errors = Off
|
||||
log_errors = On
|
||||
log_errors_max_len = 1024
|
||||
ignore_repeated_errors = Off
|
||||
ignore_repeated_source = Off
|
||||
report_memleaks = On
|
||||
html_errors = On
|
||||
error_log = syslog
|
||||
syslog.ident = php7.4
|
||||
syslog.filter = ascii
|
||||
|
||||
arg_separator.output = "&"
|
||||
variables_order = "GPCS"
|
||||
request_order = "GP"
|
||||
register_argc_argv = Off
|
||||
auto_globals_jit = On
|
||||
post_max_size = ${post_max_size}
|
||||
default_mimetype = "text/html"
|
||||
default_charset = "UTF-8"
|
||||
|
||||
enable_dl = Off
|
||||
file_uploads = On
|
||||
upload_max_filesize = ${post_max_size}
|
||||
max_file_uploads = 2000
|
||||
|
||||
allow_url_fopen = On
|
||||
allow_url_include = Off
|
||||
default_socket_timeout = 10
|
||||
|
||||
[CLI Server]
|
||||
cli_server.color = On
|
||||
|
||||
[mail function]
|
||||
mail.add_x_header = Off
|
||||
|
||||
[ODBC]
|
||||
odbc.allow_persistent = On
|
||||
odbc.check_persistent = On
|
||||
odbc.max_persistent = -1
|
||||
odbc.max_links = -1
|
||||
odbc.defaultlrl = 4096
|
||||
odbc.defaultbinmode = 1
|
||||
|
||||
[PostgreSQL]
|
||||
pgsql.allow_persistent = On
|
||||
pgsql.auto_reset_persistent = Off
|
||||
pgsql.max_persistent = -1
|
||||
pgsql.max_links = -1
|
||||
pgsql.ignore_notice = 0
|
||||
pgsql.log_notice = 0
|
||||
|
||||
[bcmath]
|
||||
bcmath.scale = 0
|
||||
|
||||
[Session]
|
||||
session.save_handler = files
|
||||
session.use_strict_mode = 0
|
||||
session.use_cookies = 1
|
||||
session.use_only_cookies = 1
|
||||
session.name = PHPSESSID
|
||||
session.auto_start = 0
|
||||
session.cookie_lifetime = 0
|
||||
session.cookie_path = /
|
||||
session.cookie_domain =
|
||||
session.cookie_httponly =
|
||||
session.cookie_samesite =
|
||||
session.serialize_handler = php
|
||||
session.gc_probability = 1
|
||||
session.gc_divisor = 1000
|
||||
session.gc_maxlifetime = 1440
|
||||
session.referer_check =
|
||||
session.cache_limiter = nocache
|
||||
session.cache_expire = 180
|
||||
session.use_trans_sid = 0
|
||||
session.sid_length = 32
|
||||
session.trans_sid_tags = "a=href,area=href,frame=src,form="
|
||||
session.sid_bits_per_character = 6
|
||||
|
||||
[Assertion]
|
||||
zend.assertions = -1
|
||||
|
||||
[Date]
|
||||
date.timezone = Europe/London
|
||||
|
||||
[opcache]
|
||||
opcache.enable = 1
|
||||
opcache.interned_strings_buffer = 32
|
||||
opcache.max_accelerated_files = 20000
|
||||
opcache.memory_consumption = 1024
|
||||
opcache.save_comments = 1
|
||||
opcache.validate_timestamps = 1
|
||||
opcache.revalidate_freq = 60
|
|
@ -1,22 +1,21 @@
|
|||
version = node.metadata.get('php/version')
|
||||
from os.path import join
|
||||
import json
|
||||
|
||||
php_ini_context = {
|
||||
'num_cpus': node.metadata.get('vm/cores'),
|
||||
'post_max_size': node.metadata.get('php/post_max_size'),
|
||||
}
|
||||
from bundlewrap.utils.dicts import merge_dict
|
||||
|
||||
|
||||
version = node.metadata.get('php/version')
|
||||
|
||||
files = {
|
||||
f'/etc/php/{version}/cli/php.ini': {
|
||||
'content_type': 'mako',
|
||||
'context': php_ini_context,
|
||||
'content': repo.libs.ini.dumps(node.metadata.get('php/php.ini')),
|
||||
'needs': {
|
||||
f'pkg_apt:php{version}',
|
||||
f'pkg_apt:php{version}-fpm',
|
||||
},
|
||||
},
|
||||
f'/etc/php/{version}/fpm/php.ini': {
|
||||
'content_type': 'mako',
|
||||
'context': php_ini_context,
|
||||
'content': repo.libs.ini.dumps(node.metadata.get('php/php.ini')),
|
||||
'needs': {
|
||||
f'pkg_apt:php{version}',
|
||||
f'pkg_apt:php{version}-fpm',
|
||||
|
|
|
@ -1,29 +1,153 @@
|
|||
defaults = {
|
||||
'php': {
|
||||
'post_max_size': '32G',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'php/php.ini',
|
||||
)
|
||||
def php_ini(metadata):
|
||||
conf = {
|
||||
'PHP': {
|
||||
'engine': 'On',
|
||||
'short_open_tag': 'Off',
|
||||
'precision': '14',
|
||||
'output_buffering': '4096',
|
||||
'zlib.output_compression': 'Off',
|
||||
'implicit_flush': 'Off',
|
||||
'serialize_precision': '-1',
|
||||
'ignore_user_abort': 'Off',
|
||||
'zend.enable_gc': 'On',
|
||||
'expose_php': 'Off',
|
||||
'max_execution_time': '300',
|
||||
'max_input_time': '600',
|
||||
'memory_limit': '512M',
|
||||
'error_reporting': '"E_ALL & ~E_DEPRECATED & ~E_STRICT"',
|
||||
'display_startup_errors': 'Off',
|
||||
'log_errors': 'On',
|
||||
'log_errors_max_len': '1024',
|
||||
'ignore_repeated_errors': 'Off',
|
||||
'ignore_repeated_source': 'Off',
|
||||
'report_memleaks': 'On',
|
||||
'html_errors': 'On',
|
||||
'error_log': 'syslog',
|
||||
'syslog.ident': 'php',
|
||||
'syslog.filter': 'ascii',
|
||||
'arg_separator.output': '"&"',
|
||||
'variables_order': 'GPCS',
|
||||
'request_order': 'GP',
|
||||
'register_argc_argv': 'Off',
|
||||
'auto_globals_jit': 'On',
|
||||
'post_max_size': '32g',
|
||||
'default_mimetype': 'text/html',
|
||||
'default_charset': 'UTF-8',
|
||||
'enable_dl': 'Off',
|
||||
'file_uploads': 'On',
|
||||
'upload_max_filesize': '32g',
|
||||
'max_file_uploads': '2000',
|
||||
'allow_url_fopen': 'On',
|
||||
'allow_url_include': 'Off',
|
||||
'default_socket_timeout': '10',
|
||||
},
|
||||
'CLI Server': {
|
||||
'cli_server.color': 'On',
|
||||
},
|
||||
'mail function': {
|
||||
'mail.add_x_header': 'Off',
|
||||
},
|
||||
'ODBC': {
|
||||
'odbc.allow_persistent': 'On',
|
||||
'odbc.check_persistent': 'On',
|
||||
'odbc.max_persistent': '-1',
|
||||
'odbc.max_links': '-1',
|
||||
'odbc.defaultlrl': '4096',
|
||||
'odbc.defaultbinmode': '1',
|
||||
},
|
||||
'PostgreSQL': {
|
||||
'pgsql.allow_persistent': 'On',
|
||||
'pgsql.auto_reset_persistent': 'Off',
|
||||
'pgsql.max_persistent': '-1',
|
||||
'pgsql.max_links': '-1',
|
||||
'pgsql.ignore_notice': '0',
|
||||
'pgsql.log_notice': '0',
|
||||
},
|
||||
'bcmath': {
|
||||
'bcmath.scale': '0',
|
||||
},
|
||||
'Session': {
|
||||
'session.save_handler': 'files',
|
||||
'session.use_strict_mode': '0',
|
||||
'session.use_cookies': '1',
|
||||
'session.use_only_cookies': '1',
|
||||
'session.name': 'PHPSESSID',
|
||||
'session.auto_start': '0',
|
||||
'session.cookie_lifetime': '0',
|
||||
'session.cookie_path': '/',
|
||||
'session.cookie_domain': '',
|
||||
'session.cookie_httponly': '',
|
||||
'session.cookie_samesite': '',
|
||||
'session.serialize_handler': 'php',
|
||||
'session.gc_probability': '1',
|
||||
'session.gc_divisor': '1000',
|
||||
'session.gc_maxlifetime': '1440',
|
||||
'session.referer_check': '',
|
||||
'session.cache_limiter': 'nocache',
|
||||
'session.cache_expire': '180',
|
||||
'session.use_trans_sid': '0',
|
||||
'session.sid_length': '32',
|
||||
'session.trans_sid_tags': '"a=href,area=href,frame=src,form="',
|
||||
'session.sid_bits_per_character': '6',
|
||||
},
|
||||
'Assertion': {
|
||||
'zend.assertions': '-1',
|
||||
},
|
||||
'Date': {
|
||||
'date.timezone': 'Europe/London',
|
||||
},
|
||||
'opcache': {
|
||||
'opcache.enable': '1',
|
||||
'opcache.interned_strings_buffer': '32',
|
||||
'opcache.max_accelerated_files': '20000',
|
||||
'opcache.memory_consumption': '1024',
|
||||
'opcache.save_comments': '1',
|
||||
'opcache.validate_timestamps': '1',
|
||||
'opcache.revalidate_freq': '60',
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
'php': {
|
||||
'php.ini': {
|
||||
section: {
|
||||
key: value
|
||||
for key, value in options.items()
|
||||
if not metadata.get(f'php/php.ini/{section}/{key}', None)
|
||||
}
|
||||
for section, options in conf.items()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'php/www.conf',
|
||||
)
|
||||
def www_conf(metadata):
|
||||
version = metadata.get('php/version')
|
||||
threads = metadata.get('vm/threads', metadata.get('vm/cores', 4))
|
||||
|
||||
return {
|
||||
'php': {
|
||||
'www.conf': {
|
||||
'user': 'www-data',
|
||||
'group': 'www-data',
|
||||
'listen': f'/run/php/php{version}-fpm.sock',
|
||||
'listen': f"/run/php/php{metadata.get('php/version')}-fpm.sock",
|
||||
'listen.owner': 'www-data',
|
||||
'listen.group': 'www-data',
|
||||
'pm': 'dynamic',
|
||||
'pm.max_children': '60',
|
||||
'pm.start_servers': '20',
|
||||
'pm.min_spare_servers': '10',
|
||||
'pm.max_spare_servers': '20',
|
||||
'pm.max_requests': '500',
|
||||
'pm.max_children': int(threads*2),
|
||||
'pm.start_servers': int(threads),
|
||||
'pm.min_spare_servers': int(threads/2),
|
||||
'pm.max_spare_servers': int(threads),
|
||||
'pm.max_requests': int(threads*32),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -33,12 +157,11 @@ def www_conf(metadata):
|
|||
'apt/packages',
|
||||
)
|
||||
def apt(metadata):
|
||||
version = metadata.get('php/version')
|
||||
return {
|
||||
'apt': {
|
||||
'packages': {
|
||||
f'php{version}': {},
|
||||
f'php{version}-fpm': {},
|
||||
f"php{metadata.get('php/version')}": {},
|
||||
f"php{metadata.get('php/version')}-fpm": {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
from bundlewrap.utils.dicts import merge_dict
|
||||
|
||||
|
||||
version = node.metadata.get('postgresql/version')
|
||||
|
||||
directories = {
|
||||
'/var/lib/postgresql': {
|
||||
'owner': 'postgres',
|
||||
'group': 'postgres',
|
||||
'needs': [
|
||||
'pkg_apt:postgresql',
|
||||
'zfs_dataset:tank/postgresql',
|
||||
f"zfs_dataset:{node.metadata.get('zfs/storage_classes/ssd')}/postgresql",
|
||||
],
|
||||
'needed_by': [
|
||||
'svc_systemd:postgresql',
|
||||
|
@ -14,6 +17,22 @@ directories = {
|
|||
}
|
||||
}
|
||||
|
||||
files = {
|
||||
f"/etc/postgresql/{version}/main/conf.d/managed.conf": {
|
||||
'content': '\n'.join(
|
||||
f'{key} = {value}'
|
||||
for key, value in sorted(node.metadata.get('postgresql/conf').items())
|
||||
) + '\n',
|
||||
'owner': 'postgres',
|
||||
'group': 'postgres',
|
||||
'needed_by': [
|
||||
'svc_systemd:postgresql',
|
||||
],
|
||||
'triggers': [
|
||||
'svc_systemd:postgresql:restart',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
svc_systemd['postgresql'] = {
|
||||
'needs': [
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import builtins
|
||||
|
||||
|
||||
root_password = repo.vault.password_for(f'{node.name} postgresql root')
|
||||
|
||||
defaults = {
|
||||
|
@ -12,6 +15,7 @@ defaults = {
|
|||
},
|
||||
},
|
||||
'postgresql': {
|
||||
'conf': {},
|
||||
'roles': {
|
||||
'root': {
|
||||
'password': root_password,
|
||||
|
@ -23,13 +27,48 @@ defaults = {
|
|||
'grafana_rows': set(),
|
||||
}
|
||||
|
||||
if node.has_bundle('zfs'):
|
||||
defaults['zfs'] = {
|
||||
'datasets': {
|
||||
'tank/postgresql': {
|
||||
'mountpoint': '/var/lib/postgresql',
|
||||
'recordsize': '8192',
|
||||
'atime': 'off',
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'postgresql/conf',
|
||||
)
|
||||
def conf(metadata):
|
||||
conf = {}
|
||||
|
||||
def limit(value, min=float('-inf'), max=float('inf'), unit=None):
|
||||
result = int(builtins.max([builtins.min([max, value]), min]))
|
||||
return str(result) + unit if unit else result
|
||||
|
||||
ram = metadata.get('vm/ram', None)
|
||||
if ram:
|
||||
conf['max_connections'] = limit(ram/50, min=100)
|
||||
conf['shared_buffers'] = limit(ram/20, min=128, unit='MB')
|
||||
conf['work_mem'] = limit(ram/500, min=4, max=64, unit='MB')
|
||||
conf['temp_buffers'] = limit(ram/500, min=8, max=64, unit='MB')
|
||||
conf['effective_cache_size'] = limit(ram/3, min=4096, unit='MB')
|
||||
conf['maintenance_work_mem'] = limit(ram/50, min=64, unit='MB')
|
||||
|
||||
return {
|
||||
'postgresql': {
|
||||
'conf': conf,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'zfs/datasets',
|
||||
)
|
||||
def zfs(metadata):
|
||||
if not node.has_bundle('zfs'):
|
||||
return {}
|
||||
|
||||
return {
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
f"{metadata.get('zfs/storage_classes/ssd')}/postgresql": {
|
||||
'mountpoint': '/var/lib/postgresql',
|
||||
'recordsize': '8192',
|
||||
'atime': 'off',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -4,3 +4,6 @@ Host *
|
|||
GSSAPIAuthentication yes
|
||||
StrictHostKeyChecking yes
|
||||
GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
|
||||
ControlMaster auto
|
||||
ControlPath ~/.ssh/multiplex-%C
|
||||
ControlPersist 5m
|
||||
|
|
48
bundles/steam-chat-logger/items.py
Normal file
48
bundles/steam-chat-logger/items.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
directories = {
|
||||
'/opt/steam_chat_logger': {
|
||||
'owner': 'steam_chat_logger',
|
||||
},
|
||||
'/var/lib/steam_chat_logger': {
|
||||
'owner': 'steam_chat_logger',
|
||||
'mode': '0755',
|
||||
'needs': [
|
||||
'zfs_dataset:tank/steam-chat-logger'
|
||||
],
|
||||
},
|
||||
'/var/lib/steam_chat_logger/steamuserimages': {
|
||||
'owner': 'steam_chat_logger',
|
||||
'mode': '0755',
|
||||
'needs': [
|
||||
'zfs_dataset:tank/steam-chat-logger'
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
git_deploy = {
|
||||
'/opt/steam_chat_logger': {
|
||||
'repo': 'https://git.sublimity.de/cronekorkn/steam_chat_logger.git',
|
||||
'rev': 'master',
|
||||
}
|
||||
}
|
||||
|
||||
pkg_pip = {
|
||||
'steam': {},
|
||||
'beautifulsoup4': {},
|
||||
'pytz': {},
|
||||
'pg8000': {},
|
||||
}
|
||||
|
||||
|
||||
# TODO
|
||||
'''
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id SERIAL PRIMARY KEY,
|
||||
checksum VARCHAR(64) UNIQUE NOT NULL,
|
||||
from_url VARCHAR(255) NOT NULL,
|
||||
from_name VARCHAR(255) NOT NULL,
|
||||
to_url VARCHAR(255) NOT NULL,
|
||||
to_name VARCHAR(255) NOT NULL,
|
||||
date TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
message TEXT NOT NULL
|
||||
)
|
||||
'''
|
51
bundles/steam-chat-logger/metadata.py
Normal file
51
bundles/steam-chat-logger/metadata.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'python3-pip': {},
|
||||
},
|
||||
},
|
||||
'postgresql': {
|
||||
'roles': {
|
||||
'steam_chat_logger': {
|
||||
'password': repo.vault.password_for(f'{node.name} postgresql steam_chat_logger'),
|
||||
},
|
||||
},
|
||||
'databases': {
|
||||
'steam_chat_logger': {
|
||||
'owner': 'steam_chat_logger',
|
||||
},
|
||||
},
|
||||
},
|
||||
'users': {
|
||||
'steam_chat_logger': {},
|
||||
},
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
'tank/steam-chat-logger': {
|
||||
'mountpoint': '/var/lib/steam_chat_logger',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd-timers/steam-chat-logger',
|
||||
)
|
||||
def systemd_timer(metadata):
|
||||
return {
|
||||
'systemd-timers': {
|
||||
f'steam-chat-logger': {
|
||||
'command': '/opt/steam_chat_logger/steam_chat_logger.py',
|
||||
'when': 'hourly',
|
||||
'user': 'steam_chat_logger',
|
||||
'env': {
|
||||
'DB_NAME': 'steam_chat_logger',
|
||||
'DB_USER': 'steam_chat_logger',
|
||||
'DB_PASSWORD': metadata.get('postgresql/roles/steam_chat_logger/password'),
|
||||
**metadata.get('steam_chat_logger'),
|
||||
},
|
||||
'working_dir': '/var/lib/steam_chat_logger',
|
||||
},
|
||||
},
|
||||
}
|
55
bundles/steam-chat-viewer/metadata.py
Normal file
55
bundles/steam-chat-viewer/metadata.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from ipaddress import ip_interface
|
||||
|
||||
defaults = {
|
||||
'flask': {
|
||||
'steam-chat-viewer' : {
|
||||
'git_url': "https://git.sublimity.de/cronekorkn/steam-chat-viewer.git",
|
||||
'port': 4001,
|
||||
'app_module': 'steam_chat_viewer',
|
||||
'user': 'steam_chat_viewer',
|
||||
'group': 'steam_chat_viewer',
|
||||
'timeout': 900,
|
||||
'env': {
|
||||
'DB_HOST': 'localhost',
|
||||
'DB_NAME': 'steam_chat_logger',
|
||||
'DB_USER': 'steam_chat_logger',
|
||||
},
|
||||
},
|
||||
},
|
||||
'users': {
|
||||
'steam_chat_viewer': {},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'flask/steam-chat-viewer/env/DB_PASSWORD',
|
||||
)
|
||||
def agent_conf(metadata):
|
||||
return {
|
||||
'flask': {
|
||||
'steam-chat-viewer': {
|
||||
'env': {
|
||||
'DB_PASSWORD': metadata.get('postgresql/roles/steam_chat_logger/password'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nginx/vhosts',
|
||||
)
|
||||
def nginx(metadata):
|
||||
return {
|
||||
'nginx': {
|
||||
'vhosts': {
|
||||
metadata.get('steam-chat-viewer/hostname'): {
|
||||
'content': 'steam-chat-viewer/vhost.conf',
|
||||
'context': {
|
||||
'target': 'http://127.0.0.1:4001',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
|
@ -54,6 +54,6 @@ actions = {
|
|||
svc_systemd['steam-update'] = {
|
||||
'running': False,
|
||||
'needs': {
|
||||
'file:/etc/systemd/system/steam-update.service',
|
||||
'file:/usr/local/lib/systemd/system/steam-update.service',
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,56 @@
|
|||
size = node.metadata.get('systemd-swap')
|
||||
assert isinstance(size, int)
|
||||
size_mb = node.metadata.get('systemd-swap')//1_000_000
|
||||
|
||||
actions = {
|
||||
'stop_swap': {
|
||||
'command': f'systemctl stop swapfile.swap',
|
||||
'unless': f'rm /swapfile',
|
||||
'unless': f'! systemctl is-active swapfile.swap',
|
||||
'triggered': True,
|
||||
},
|
||||
'remove_swapfile': {
|
||||
'command': f'rm /swapfile',
|
||||
'unless': f'! test -e /swapfile',
|
||||
'triggered': True,
|
||||
'needs': {
|
||||
'action:stop_swap',
|
||||
},
|
||||
},
|
||||
'create_swapfile': {
|
||||
'command': f'dd if=/dev/zero of=/swapfile bs={size} count=1',
|
||||
'unless': f'stat -c %s /swapfile | grep ^{size}$',
|
||||
'command': f'dd if=/dev/zero of=/swapfile bs=1000000 count={size_mb}',
|
||||
'unless': f'stat -c %s /swapfile | grep ^{size_mb*1_000_000}$',
|
||||
'preceded_by': {
|
||||
'action:stop_swap',
|
||||
'action:remove_swapfile',
|
||||
},
|
||||
'triggers': {
|
||||
'action:initialize_swapfile',
|
||||
'svc_systemd:swapfile.swap:restart',
|
||||
},
|
||||
},
|
||||
'swapfile_mode': {
|
||||
'command': f'chmod 600 /swapfile',
|
||||
'unless': f'stat -c "%a" /swapfile | grep -q "^600$"',
|
||||
'needs': {
|
||||
'action:create_swapfile',
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:swapfile.swap:restart',
|
||||
},
|
||||
},
|
||||
'initialize_swapfile': {
|
||||
'command': f'mkswap /swapfile',
|
||||
'triggered': True,
|
||||
'needs': {
|
||||
'action:create_swapfile',
|
||||
'action:swapfile_mode',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
files = {
|
||||
'/swapfile': {
|
||||
'content_type': 'any',
|
||||
'mode': '600',
|
||||
'triggers': {
|
||||
'svc_systemd:swapfile.swap:restart',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
svc_systemd = {
|
||||
'swapfile.swap': {
|
||||
'preceded_by': {
|
||||
'action:initialize_swapfile',
|
||||
},
|
||||
'needs': {
|
||||
'file:/swapfile',
|
||||
'action:initialize_swapfile',
|
||||
'action:systemd-reload',
|
||||
},
|
||||
|
|
|
@ -22,7 +22,7 @@ def systemd(metadata):
|
|||
'Persistent': config.get('persistent', False),
|
||||
'Unit': f'{name}.service',
|
||||
},
|
||||
},
|
||||
},
|
||||
f'{name}.service': {
|
||||
'Unit':{
|
||||
'Description': f'{name} timer service',
|
||||
|
@ -30,11 +30,18 @@ def systemd(metadata):
|
|||
'Service': {
|
||||
'User': config.get('user', 'root'),
|
||||
'ExecStart': config['command'],
|
||||
'Environment': config.get('env'),
|
||||
'Nice': config.get('nice', 10),
|
||||
},
|
||||
},
|
||||
})
|
||||
if config.get('working_dir'):
|
||||
units[f'{name}.service']['Service']['WorkingDirectory'] = config['working_dir']
|
||||
if config.get('success_exit_status'):
|
||||
units[f'{name}.service']['Service']['SuccessExitStatus'] = config['success_exit_status']
|
||||
|
||||
services[f'{name}.timer'] = {}
|
||||
|
||||
|
||||
return {
|
||||
'systemd': {
|
||||
'units': units,
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# SYSTEMD
|
||||
|
||||
## show unit paths
|
||||
|
||||
```
|
||||
systemctl --no-pager --property=UnitPath show | tr ' ' '\n'
|
||||
```
|
||||
|
||||
## metadata
|
||||
|
||||
```python
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
from bundlewrap.utils.dicts import merge_dict
|
||||
|
||||
directories = {
|
||||
'/usr/local/lib/systemd/system': {
|
||||
'purge': True,
|
||||
'triggers': [
|
||||
"action:systemd-reload",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
actions = {
|
||||
'systemd-reload': {
|
||||
'command': 'systemctl daemon-reload',
|
||||
|
@ -22,7 +31,7 @@ for name, unit in node.metadata.get('systemd/units').items():
|
|||
],
|
||||
}
|
||||
elif extension in ['timer', 'service', 'mount', 'swap']:
|
||||
path = f'/etc/systemd/system/{name}'
|
||||
path = f'/usr/local/lib/systemd/system/{name}'
|
||||
dependencies = {
|
||||
'triggers': [
|
||||
"action:systemd-reload",
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
# Phone
|
||||
|
||||
- install termux from Play Store
|
||||
- install termux::api from Play Store
|
||||
- install termux from F-Droid
|
||||
- install termux::api from F-Droid
|
||||
- open termux
|
||||
- run `pkg update`
|
||||
- run `pkg install termux-api openssh`
|
||||
- run `passwd` and set a password
|
||||
- run `whoami` to get the username
|
||||
- run `sshd` to start ssh server
|
||||
- run `su - tasmota-charge -c 'ssh-copy-id -p 8022 u0_a233@10.0.0.175'` on server node
|
||||
- acquire wakelock for the termux session in notifications
|
||||
- install termux::boot from F-Droid
|
||||
- create file ~/.termux/boot/start-sshd:
|
||||
```shell
|
||||
#!/data/data/com.termux/files/usr/bin/sh
|
||||
termux-wake-lock
|
||||
sshd
|
||||
```
|
||||
|
||||
# Server
|
||||
|
||||
- you can run something like `su - tasmota-charge -c 'ssh-copy-id -p 8022 u0_q194@10.0.0.166'`
|
||||
- you can run something like `su - tasmota-charge -c 'ssh -p 8022 u0_a233@10.0.0.175'`
|
||||
|
|
|
@ -6,16 +6,26 @@ PLUG_IP=${plug_ip}
|
|||
MIN=${min}
|
||||
MAX=${max}
|
||||
|
||||
AKKU=$(ssh -p 8022 $PHONE_USER@$PHONE_IP termux-battery-status | jq -r .percentage)
|
||||
echo "akku is at $AKKU%"
|
||||
if ! ssh -o 'StrictHostKeyChecking no' -p 8022 $PHONE_USER@$PHONE_IP 'true'
|
||||
then
|
||||
echo "ERROR: cant connect to phone via ssh"
|
||||
exit 51
|
||||
fi
|
||||
AKKU=$(ssh -o 'StrictHostKeyChecking no' -p 8022 $PHONE_USER@$PHONE_IP termux-battery-status | jq -r .percentage)
|
||||
echo "akku is at $AKKU% ($MIN%/$MAX%)"
|
||||
|
||||
if ! curl --head --silent --fail "http://$PLUG_IP/cm?cmnd=Power" --output /dev/null
|
||||
then
|
||||
echo "ERROR: cant connect to plug via http"
|
||||
exit 52
|
||||
fi
|
||||
PLUG_IS=$(curl -s "http://$PLUG_IP/cm?cmnd=Power" | jq -r .POWER)
|
||||
echo "plug is $PLUG_IS"
|
||||
|
||||
if [[ $AKKU < $MIN ]] && [[ $PLUG_IS = OFF ]]
|
||||
if [[ $AKKU -lt $MIN ]] && [[ $PLUG_IS = OFF ]]
|
||||
then
|
||||
TURN_PLUG=ON
|
||||
elif [[ $AKKU > $MAX ]] && [[ $PLUG_IS = ON ]]
|
||||
elif [[ $AKKU -gt $MAX ]] && [[ $PLUG_IS = ON ]]
|
||||
then
|
||||
TURN_PLUG=OFF
|
||||
else
|
||||
|
@ -24,4 +34,11 @@ else
|
|||
fi
|
||||
|
||||
echo "turning plug $TURN_PLUG"
|
||||
curl -s "http://$PLUG_IP/cm?cmnd=Power%20$TURN_PLUG"
|
||||
if curl --silent "http://$PLUG_IP/cm?cmnd=Power%20$TURN_PLUG" | jq -r .POWER | grep -q "^$TURN_PLUG\$"
|
||||
then
|
||||
echo "SUCCESS"
|
||||
exit 0
|
||||
else
|
||||
echo "ERROR"
|
||||
exit 53
|
||||
fi
|
||||
|
|
|
@ -20,6 +20,11 @@ files = {
|
|||
'source': f"https://dl.sublimity.de/telegraf-procio/telegraf-procio-{node.metadata.get('system/architecture')}-latest",
|
||||
'mode': '0755',
|
||||
},
|
||||
'/usr/local/share/telegraf/pressure_stall': {
|
||||
'content_type': 'download',
|
||||
'source': f"https://dl.sublimity.de/telegraf-pressure-stall/telegraf-pressure-stall-{node.metadata.get('system/architecture')}-latest",
|
||||
'mode': '0755',
|
||||
},
|
||||
}
|
||||
|
||||
svc_systemd['telegraf'] = {
|
||||
|
|
|
@ -5,9 +5,6 @@ defaults = {
|
|||
'packages': {
|
||||
'telegraf': {},
|
||||
},
|
||||
'sources': {
|
||||
'deb https://repos.influxdata.com/debian {release} stable',
|
||||
},
|
||||
},
|
||||
'telegraf': {
|
||||
'config': {
|
||||
|
@ -48,20 +45,31 @@ defaults = {
|
|||
'memory_rss',
|
||||
],
|
||||
})},
|
||||
'diskio': {h({})},
|
||||
'diskio': {h({
|
||||
'device_tags': ["ID_PART_ENTRY_NUMBER"],
|
||||
})},
|
||||
'kernel': {h({})},
|
||||
'mem': {h({})},
|
||||
'processes': {h({})},
|
||||
'swap': {h({})},
|
||||
'system': {h({})},
|
||||
'net': {h({})},
|
||||
'exec': {h({
|
||||
'commands': [
|
||||
f'sudo /usr/local/share/telegraf/procio',
|
||||
],
|
||||
'data_format': 'influx',
|
||||
'interval': '20s',
|
||||
})},
|
||||
'exec': {
|
||||
h({
|
||||
'commands': [
|
||||
f'sudo /usr/local/share/telegraf/procio',
|
||||
],
|
||||
'data_format': 'influx',
|
||||
'interval': '20s',
|
||||
}),
|
||||
h({
|
||||
'commands': [
|
||||
f'/usr/local/share/telegraf/pressure_stall',
|
||||
],
|
||||
'data_format': 'influx',
|
||||
'interval': '10s',
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -71,8 +79,7 @@ defaults = {
|
|||
'disk_io',
|
||||
'disk_usage',
|
||||
'net_io',
|
||||
'proc_cpu',
|
||||
'proc_ram',
|
||||
'proc_cpu_ram',
|
||||
'proc_io',
|
||||
},
|
||||
'sudoers': {
|
||||
|
@ -81,6 +88,28 @@ defaults = {
|
|||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'apt/sources',
|
||||
)
|
||||
def apt(metadata):
|
||||
release = {
|
||||
'buster': 'buster',
|
||||
'bullseye': 'bullseye',
|
||||
'bookworm': 'bullseye',
|
||||
}[metadata.get('os_release')]
|
||||
|
||||
return {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'telegraf': {},
|
||||
},
|
||||
'sources': {
|
||||
f"deb https://repos.influxdata.com/debian {release} stable",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'telegraf/config/outputs/influxdb_v2',
|
||||
)
|
||||
|
|
|
@ -1,40 +1,73 @@
|
|||
#!/bin/bash
|
||||
|
||||
WOKE=$(expr $(journalctl -t systemd-sleep -b 0 -o json MESSAGE="System resumed." -n1 | jq -r .__REALTIME_TIMESTAMP) / 1000000)
|
||||
NOW=$(date +%s)
|
||||
UPTIME=$(expr $NOW - $WOKE)
|
||||
# CHECK UPTIME
|
||||
|
||||
RESUMED_TIMESTAMP_MICRO=$(journalctl -t systemd-sleep -b 0 -o json MESSAGE="System resumed." -n1 | jq -r .__REALTIME_TIMESTAMP)
|
||||
if [[ -z "$RESUMED_TIMESTAMP_MICRO" ]]
|
||||
then
|
||||
UPTIME=$(cat /proc/uptime | cut -d' ' -f1 | cut -d'.' -f1)
|
||||
else
|
||||
RESUMED_TIMESTAMP=$(expr $RESUMED_TIMESTAMP_MICRO / 1000000)
|
||||
NOW_TIMESTAMP=$(date +%s)
|
||||
UPTIME=$(expr $NOW_TIMESTAMP - $RESUMED_TIMESTAMP)
|
||||
fi
|
||||
|
||||
|
||||
MIN_UPTIME=$(expr 60 \* 15)
|
||||
if [[ "$UPTIME" -lt "$MIN_UPTIME" ]]
|
||||
then
|
||||
echo "ABORT: uptime ($UPTIME s) lower than minimum ($MIN_UPTIME s)"
|
||||
exit 0
|
||||
echo "ABORT: uptime of ${UPTIME}s is lower than minimum of ${MIN_UPTIME}s"
|
||||
exit 75
|
||||
fi
|
||||
|
||||
MY_SERVICE="$2"
|
||||
# CHECK FOR RUNNING TIMERS
|
||||
|
||||
for SERVICE in $(systemctl list-timers --no-pager --no-legend --state active -o json | jq -r '.[] | .activates')
|
||||
do
|
||||
if [[ "$SERVICE" = "$MY_SERVICE" ]]
|
||||
if [[ "$SERVICE" = "$THIS_SERVICE" ]]
|
||||
then
|
||||
continue
|
||||
elif systemctl is-active "$SERVICE" --quiet
|
||||
then
|
||||
echo "ABORT: service $SERVICE is running by timer"
|
||||
exit 0
|
||||
exit 75
|
||||
fi
|
||||
done
|
||||
|
||||
LOGINS=$(netstat -tnpa | grep 'ESTABLISHED.*sshd' | wc -l)
|
||||
if [[ "$LOGINS" -gt 0 ]]
|
||||
# CHECK FOR ACTIVE LOGINS
|
||||
|
||||
LOGINS=$(netstat -tnpa | grep 'ESTABLISHED.*sshd' | tr -s ' ' | cut -d' ' -f5,7-8 | paste -d',' -s | sed 's/,/, /')
|
||||
if ! [[ -z "$LOGINS" ]]
|
||||
then
|
||||
echo "ABORT: $LOGINS user logins"
|
||||
exit 0
|
||||
echo "ABORT: users logged in: $LOGINS"
|
||||
exit 75
|
||||
fi
|
||||
|
||||
if [[ "$1" = now ]]
|
||||
# SUSPEND!
|
||||
|
||||
if [[ "$1" = check ]]
|
||||
then
|
||||
echo "SESPENDING"
|
||||
sleep 60
|
||||
systemctl suspend
|
||||
else
|
||||
echo "WOULD SESPEND"
|
||||
exit 0
|
||||
else
|
||||
echo "SESPENDING AFTER TIMEOUT"
|
||||
|
||||
for i in 1 2 3 4 5 6
|
||||
do
|
||||
echo "TIMEOUT ${i} success"
|
||||
sleep 10
|
||||
|
||||
# check if condition is still met
|
||||
if "$0" check
|
||||
then
|
||||
continue
|
||||
else
|
||||
echo "SESPENSION ABORTED"
|
||||
exit 75
|
||||
fi
|
||||
done
|
||||
|
||||
echo "SESPENDING"
|
||||
systemctl suspend
|
||||
exit 0
|
||||
fi
|
||||
|
|
|
@ -3,7 +3,7 @@ if not waker_node.has_bundle('wol-waker'):
|
|||
raise Exception(f'waker node {waker_node.name} does not have bundle wol-waker')
|
||||
|
||||
files = {
|
||||
'/opt/suspend_if_idle': {
|
||||
'/usr/local/bin/suspend_if_idle': {
|
||||
'mode': '550',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ defaults = {
|
|||
'apt': {
|
||||
'packages': {
|
||||
'jq': {},
|
||||
'ethtool': {},
|
||||
'net-tools': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -14,12 +16,15 @@ defaults = {
|
|||
'systemd-timers/suspend-if-idle',
|
||||
)
|
||||
def timer(metadata):
|
||||
name = 'suspend-if-idle'#
|
||||
return {
|
||||
'systemd-timers': {
|
||||
name: {
|
||||
'command': f'/opt/suspend_if_idle now {name}.service',
|
||||
'suspend-if-idle': {
|
||||
'command': f'suspend_if_idle',
|
||||
'when': 'minutely',
|
||||
'success_exit_status': '75',
|
||||
'env': {
|
||||
'THIS_SERVICE': 'suspend-if-idle.service',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -32,7 +37,7 @@ def wake_command(metadata):
|
|||
waker_hostname = repo.get_node(metadata.get('wol-sleeper/waker')).hostname
|
||||
mac = metadata.get(f"network/{metadata.get('wol-sleeper/network')}/mac")
|
||||
ip = ip_interface(metadata.get(f"network/{metadata.get('wol-sleeper/network')}/ipv4")).ip
|
||||
|
||||
|
||||
return {
|
||||
'wol-sleeper': {
|
||||
'wake_command': f"ssh -o StrictHostKeyChecking=no wol@{waker_hostname} 'wakeonlan {mac} && while ! ping {ip} -c1 -W3; do true; done'",
|
||||
|
@ -41,19 +46,13 @@ def wake_command(metadata):
|
|||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'apt/packages/ethtool',
|
||||
'systemd/units/enable-wol.service',
|
||||
'systemd/services/enable-wol.service',
|
||||
)
|
||||
def systemd(metadata):
|
||||
interface = metadata.get(f"network/{metadata.get('wol-sleeper/network')}/interface")
|
||||
|
||||
|
||||
return {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'ethtool': {},
|
||||
},
|
||||
},
|
||||
'systemd': {
|
||||
'units': {
|
||||
'enable-wol.service': {
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
defaults = {
|
||||
'apt': {
|
||||
'packages': {
|
||||
'wakeonlan': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'users/wol',
|
||||
)
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
set -exu
|
||||
|
||||
ssh="ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@${server_ip}"
|
||||
ssh="ssh -o ConnectTimeout=5 root@${server_ip}"
|
||||
bookmark_prefix="auto-mirror_"
|
||||
new_bookmark="$bookmark_prefix$(date +"%Y-%m-%d_%H:%M:%S")"
|
||||
|
||||
for dataset in $(zfs list -t filesystem -H -o name)
|
||||
do
|
||||
echo "MIRRORING $dataset"
|
||||
|
||||
|
||||
if ! $ssh sudo zfs list -t filesystem -H -o name | grep -q "^$dataset$"
|
||||
then
|
||||
echo "CREATING PARENT DATASET..."
|
||||
|
@ -17,11 +17,11 @@ do
|
|||
fi
|
||||
|
||||
zfs snap "$dataset@$new_bookmark"
|
||||
|
||||
|
||||
if zfs list -t bookmark -H -o name | grep "^$dataset#$bookmark_prefix" | wc -l | grep -q "^0$"
|
||||
then
|
||||
echo "INITIAL BACKUP"
|
||||
# do in subshell, otherwise ctr+c will lead to 0 exitcode
|
||||
# do in subshell, otherwise ctr+c will lead to 0 exitcode
|
||||
$(zfs send -v "$dataset@$new_bookmark" | $ssh sudo zfs recv -F "$dataset" -o mountpoint=none)
|
||||
else
|
||||
echo "INCREMENTAL BACKUP"
|
||||
|
@ -32,6 +32,19 @@ do
|
|||
|
||||
if [[ "$?" == "0" ]]
|
||||
then
|
||||
|
||||
# delete old local bookmarks
|
||||
for destroyable_bookmark in $(zfs list -t bookmark -H -o name "$dataset" | grep "^$dataset#$bookmark_prefix")
|
||||
do
|
||||
zfs destroy "$destroyable_bookmark"
|
||||
done
|
||||
|
||||
# delete snapshots from bookmarks (except newest, even of not necessary; maybe for resuming tho)
|
||||
for destroyable_snapshot in $($ssh sudo zfs list -t snapshot -H -o name "$dataset" | grep "^$dataset@$bookmark_prefix" | grep -v "$new_bookmark")
|
||||
do
|
||||
$ssh sudo zfs destroy "$destroyable_snapshot"
|
||||
done
|
||||
|
||||
zfs bookmark "$dataset@$new_bookmark" "$dataset#$new_bookmark"
|
||||
zfs destroy "$dataset@$new_bookmark"
|
||||
echo "SUCCESS $dataset"
|
||||
|
|
|
@ -45,24 +45,6 @@ defaults = {
|
|||
'when': '*-2,4,6,8,10,12-1 02:00',
|
||||
'persistent': True,
|
||||
},
|
||||
'zfs-auto-snapshot-hourly': {
|
||||
'command': '/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=hourly --keep=24 //',
|
||||
'when': 'hourly',
|
||||
},
|
||||
'zfs-auto-snapshot-daily': {
|
||||
'command': '/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=daily --keep=7 //',
|
||||
'when': 'daily',
|
||||
},
|
||||
'zfs-auto-snapshot-weekly': {
|
||||
'command': '/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=weekly --keep=4 //',
|
||||
'when': 'weekly',
|
||||
'persistent': True,
|
||||
},
|
||||
'zfs-auto-snapshot-monthly': {
|
||||
'command': '/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=monthly --keep=24 //',
|
||||
'when': 'monthly',
|
||||
'persistent': True,
|
||||
},
|
||||
},
|
||||
'telegraf': {
|
||||
'config': {
|
||||
|
@ -78,9 +60,19 @@ defaults = {
|
|||
'datasets': {},
|
||||
'pools': {},
|
||||
'kernel_params': {},
|
||||
'storage_classes': {
|
||||
'ssd': 'tank',
|
||||
},
|
||||
'auto_snapshots': {
|
||||
'hourly': 24,
|
||||
'daily': 7,
|
||||
'weekly': 4,
|
||||
'monthly': 24,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'zfs/datasets'
|
||||
)
|
||||
|
@ -120,7 +112,7 @@ def headers(metadata):
|
|||
arch = 'arm64'
|
||||
else:
|
||||
arch = 'amd64'
|
||||
|
||||
|
||||
return {
|
||||
'apt': {
|
||||
'packages': {
|
||||
|
@ -132,3 +124,62 @@ def headers(metadata):
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'zfs/kernel_params/zfs_arc_max',
|
||||
)
|
||||
def arc_size(metadata):
|
||||
arc_percent = metadata.get('zfs/zfs_arc_max_percent', None)
|
||||
|
||||
if arc_percent:
|
||||
return {
|
||||
'zfs': {
|
||||
'kernel_params': {
|
||||
'zfs_arc_max': str(int(
|
||||
metadata.get('vm/ram') * 1024 * 1024 * (arc_percent/100)
|
||||
)),
|
||||
},
|
||||
},
|
||||
}
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd-timers/zfs-auto-snapshot-hourly',
|
||||
'systemd-timers/zfs-auto-snapshot-daily',
|
||||
'systemd-timers/zfs-auto-snapshot-weekly',
|
||||
'systemd-timers/zfs-auto-snapshot-monthly',
|
||||
)
|
||||
def auto_snapshots(metadata):
|
||||
hourly = metadata.get('zfs/auto_snapshots/hourly')
|
||||
daily = metadata.get('zfs/auto_snapshots/daily')
|
||||
weekly = metadata.get('zfs/auto_snapshots/weekly')
|
||||
monthly = metadata.get('zfs/auto_snapshots/monthly')
|
||||
|
||||
# cant be 0
|
||||
assert hourly > 0 and daily > 0 and weekly > 0 and monthly > 0
|
||||
|
||||
return {
|
||||
'systemd-timers': {
|
||||
'zfs-auto-snapshot-hourly': {
|
||||
'command': f'/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=hourly --keep={hourly} //',
|
||||
'when': 'hourly',
|
||||
},
|
||||
'zfs-auto-snapshot-daily': {
|
||||
'command': f'/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=daily --keep={daily} //',
|
||||
'when': 'daily',
|
||||
},
|
||||
'zfs-auto-snapshot-weekly': {
|
||||
'command': f'/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=weekly --keep={weekly} //',
|
||||
'when': 'weekly',
|
||||
'persistent': True,
|
||||
},
|
||||
'zfs-auto-snapshot-monthly': {
|
||||
'command': f'/usr/sbin/zfs-auto-snapshot --quiet --syslog --label=monthly --keep={monthly} //',
|
||||
'when': 'monthly',
|
||||
'persistent': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function spwd {
|
||||
function zsh_spwd {
|
||||
paths=(${(s:/:)PWD})
|
||||
|
||||
cur_path='/'
|
||||
|
@ -21,9 +21,20 @@ function spwd {
|
|||
echo
|
||||
}
|
||||
|
||||
indicator="$(hostname -s)"
|
||||
local ret_status="%(?:%{$fg_bold[green]%}$indicator:%{$fg_bold[red]%}$indicator)"
|
||||
PROMPT='${ret_status} %{$fg[cyan]%}$(spwd)%{$reset_color%} $(git_prompt_info)'
|
||||
function zsh_root_color {
|
||||
if test "$EUID" -eq 0
|
||||
then
|
||||
echo "%{$fg_bold[green]%}"
|
||||
else
|
||||
echo "%{$fg_bold[yellow]%}"
|
||||
fi
|
||||
}
|
||||
|
||||
function zsh_exitcode_color {
|
||||
echo "%(?:%{$fg_bold[green]%}:%{$fg_bold[red]%})"
|
||||
}
|
||||
|
||||
PROMPT='$(zsh_root_color)$(whoami)%{$reset_color%}@$(zsh_exitcode_color)$(hostname -s) %{$fg[cyan]%}$(zsh_spwd)%{$reset_color%} $(git_prompt_info)'
|
||||
|
||||
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
|
||||
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
|
||||
|
|
22
bundles/zsh/files/zprofile
Normal file
22
bundles/zsh/files/zprofile
Normal file
|
@ -0,0 +1,22 @@
|
|||
# /etc/zsh/zprofile: system-wide .zprofile file for zsh(1).
|
||||
#
|
||||
# This file is sourced only for login shells (i.e. shells
|
||||
# invoked with "-" as the first character of argv[0], and
|
||||
# shells invoked with the -l flag.)
|
||||
#
|
||||
# Global Order: zshenv, zprofile, zshrc, zlogin
|
||||
|
||||
alias s='sudo su - root -s /usr/bin/zsh'
|
||||
|
||||
function hhtop {
|
||||
mkdir -p ~/.config/htop
|
||||
cp /etc/htoprc.global ~/.config/htop/htoprc
|
||||
htop
|
||||
}
|
||||
|
||||
ZSH_THEME=bw
|
||||
DISABLE_AUTO_UPDATE=true
|
||||
plugins=(
|
||||
zsh-autosuggestions
|
||||
)
|
||||
source /etc/zsh/oh-my-zsh/oh-my-zsh.sh
|
|
@ -1,6 +0,0 @@
|
|||
export ZSH=~/.zsh/oh-my-zsh
|
||||
ZSH_THEME=bw
|
||||
plugins=(
|
||||
zsh-autosuggestions
|
||||
)
|
||||
source $ZSH/oh-my-zsh.sh
|
|
@ -1,46 +1,44 @@
|
|||
from os.path import join
|
||||
|
||||
directories = {
|
||||
'/etc/zsh/oh-my-zsh': {},
|
||||
'/etc/zsh/oh-my-zsh/custom/plugins': {
|
||||
'mode': '0755',
|
||||
'needs': [
|
||||
f"git_deploy:/etc/zsh/oh-my-zsh",
|
||||
]
|
||||
},
|
||||
'/etc/zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions': {
|
||||
'needs': [
|
||||
f"git_deploy:/etc/zsh/oh-my-zsh",
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
git_deploy = {
|
||||
'/etc/zsh/oh-my-zsh': {
|
||||
'repo': 'https://github.com/ohmyzsh/ohmyzsh.git',
|
||||
'rev': 'master',
|
||||
},
|
||||
'/etc/zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions': {
|
||||
'repo': 'https://github.com/zsh-users/zsh-autosuggestions.git',
|
||||
'rev': 'master',
|
||||
},
|
||||
}
|
||||
|
||||
files = {
|
||||
'/etc/zsh/zprofile': {},
|
||||
'/etc/zsh/oh-my-zsh/themes/bw.zsh-theme': {
|
||||
'needs': [
|
||||
f"git_deploy:/etc/zsh/oh-my-zsh",
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
for name, user_config in node.metadata.get('users').items():
|
||||
if user_config.get('shell', None) != '/usr/bin/zsh':
|
||||
continue
|
||||
|
||||
directories = {
|
||||
join(user_config['home'], '.zsh'): {
|
||||
files[join(user_config['home'], '.zshrc')] = {
|
||||
'owner': name,
|
||||
},
|
||||
join(user_config['home'], '.zsh/oh-my-zsh'): {
|
||||
'owner': name,
|
||||
},
|
||||
join(user_config['home'], '.zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions'): {
|
||||
'owner': name,
|
||||
'needs': [
|
||||
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}",
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
git_deploy = {
|
||||
join(user_config['home'], '.zsh/oh-my-zsh'): {
|
||||
'repo': 'https://github.com/ohmyzsh/ohmyzsh.git',
|
||||
'rev': 'master',
|
||||
},
|
||||
join(user_config['home'], '.zsh/oh-my-zsh/custom/plugins/zsh-autosuggestions'): {
|
||||
'repo': 'https://github.com/zsh-users/zsh-autosuggestions.git',
|
||||
'rev': 'master',
|
||||
},
|
||||
}
|
||||
|
||||
files = {
|
||||
join(user_config['home'], '.zshrc'): {
|
||||
'owner': name,
|
||||
'source': 'zshrc',
|
||||
},
|
||||
join(user_config['home'], '.zsh/oh-my-zsh/themes/bw.zsh-theme'): {
|
||||
'owner': name,
|
||||
'needs': [
|
||||
f"git_deploy:{join(user_config['home'], '.zsh/oh-my-zsh')}",
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
'group': name,
|
||||
'content': '# bw managed',
|
||||
}
|
||||
|
|
41
data/apt/keys/repo.delellis.com.ar.asc
Normal file
41
data/apt/keys/repo.delellis.com.ar.asc
Normal file
|
@ -0,0 +1,41 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQGNBF5qU5ABDAC5P4yAxACWwvknjaREtCjSpqwpVKbP+HCQcaho3ao/ls2mUQ7K
|
||||
WzqoAknFljZACkoQT6D+9t0Wx+aYhSb8kc/RHDoQQN5w7sAxBCsUS0/unF7PQxZH
|
||||
px3YTJgTlkl7cB79pbK5mu/Ybj/AhtjLwuu5CO8xPK19K2Xl1TT14sWlfxVmNxJ1
|
||||
X62w2lPfHuS1GJKw5k32ee3UeZB2FAuwzO84FlvlmoSgiGgOSW+OPLxapZA0glO3
|
||||
M/FpjF/ergaQqbU3nAaPkj3J7by7+j2r81RJZ49s9RXPUHie8d5TDB53KWaOTHPh
|
||||
ONF3pssaWeEMP3Ju23s1t9dV1hPtwzdTiXu3lQp+0eZy4X085tEGsz4oYxAXlG2X
|
||||
gXKR9wO8AhzN6E2UJRDPjiXD8APDh5SDxNreFFTv9orh+dRHjaFQuds0erkDVc9g
|
||||
CDkczKy8zi14BEdWolPHNp6rVdbtyFKhiCrr9MOQEGJ04FgIB6HDbaAAXEUe7oU4
|
||||
0v1i0BXFrCVDNx8AEQEAAbQlTWF0aWFzIERlIGxlbGxpcyA8bWF0aTg2ZGxAZ21h
|
||||
aWwuY29tPokB1AQTAQgAPgIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgBYhBIMH
|
||||
yrK2G/QHU3ipTjkheTntPQfbBQJiOGH3BQkHkHVnAAoJEDkheTntPQfbQ28MAIw3
|
||||
yz+CJWP60ypv/W4ErUif0bhwMsSG+5YPligOcSmgzw9x3xysPSLpBrBR5cpLCx8Z
|
||||
voqFa5PJbu8cKhmHGQMvH7duVPL6gRX4dQG9t9qtKd9DYmsD9GweyCWFIhVFTId4
|
||||
VyDeEqx1IWAHyLoJmfnCQAIZHwhPrZKVU2hui8YjqZ4bpuP/xKGBiREgkPP5yv/T
|
||||
J0GPoH9JOe67V9pDDN71cJzJpbFG7bPwH5LkzhO2fS6StyLKG7rMJHo6y2B9tWET
|
||||
4V18WKotn1rT2gBunoCE3NsazwnXFf1C/KnHZF8zYAtLZfFa2gz4JgLk4kCgKeUO
|
||||
vKubOoF44BFad6hgXA2yFiY7LXZmUhydlIdMp9P67jdmosW6Rbjz3st/nqg6pmjM
|
||||
pMFEoc2jybdbiWkppRmrQlwRD76ir1Fcu71eEDZIPCfHpBNEyMgtdL/zyJnUbtGl
|
||||
Bp8Jpfg9Y3CqDXtBkUug6KQ77S61zRnaenD91V2NrMnHVQsoiNP42h//7feTiLkB
|
||||
jQRealOQAQwA2YM6vfJbo+BkFSmjwpuvY65DzVDyz4nRO1NvHBHeuMJKeWgF5pKe
|
||||
e/TOJWcjlsBT2xwsqi8NhT1O2BpVBXOGN2Ck6YLQ0WPaxfsmAEGCyVFsJIBuWOQ7
|
||||
j0VXyvbHbUGrcLg5sA3VS0zzqquMf7dAwHI7earp1HsOd8DvRs518leRx18wiDap
|
||||
6UbPqpu3yFqNY4oeZ7oBpII6olm9YtGGP0mHquPYpWq9ZlN1vjPbLgjY1IPs2OMl
|
||||
DGE1eaEWeygyL1tRgjAGpgsdLS3BOgF1fY0OpTRyZnez+W8eWqTB12yF17FpErWC
|
||||
VeO8h6LosfjcQ8Bg2WQnFrzJJgXzVxrvwygbtggvN/feEPzWJg92TEQLzMFRf8I9
|
||||
rCju5SOR5WBTPmvnq7f9VT/2rg0WSBjkVxGq9wMVyXmOOkYUB6hx5ynDEM9cIzG3
|
||||
Jmvm+rz1lQiILwnpFXUtTWnQbMuUmdPWFM2f2XKRY0RE0EvJ4K5ve49bz+SvOUip
|
||||
ewVowQ46z0LZABEBAAGJAbwEGAEIACYCGwwWIQSDB8qythv0B1N4qU45IXk57T0H
|
||||
2wUCYjhiLwUJB5B1nwAKCRA5IXk57T0H2/7jDACqur/sIYzTSxUEn73yyde6S8za
|
||||
ZzcnzV9JIIi9vTVd50J5ngWjg06PPYe6NXSf6J/EXxHOp2TKy58FPyMnxBENzycM
|
||||
P+9GyH4UH3nOK8ywgZ7nkyXYjJKzZ+88F9HcUgO3xSwsMy6kpeIdxXI3fpEOVXBn
|
||||
lAsHM6CF1Nk5O4oxgJwgbXwf5ntYDeXwcpm6NCdDTorYLy5JvhDg8XiTeMl6fFki
|
||||
uDSrNF0UNkkhutS/66FVLUlq5grSWH7mYviau6Ju2C2Tq2GijvRcvkQcA37Mx//x
|
||||
x4ydNydSmu5kxfB6JorgAnK8sLTIHU+RWgmJRly5YY/G6RXm2QsYs+RvObgIablW
|
||||
k1ZXNcb3qEyn3D91sXUsvp7qMAnQjWp2UkV4KygMc6C4i54JkOTcZiGhynjB6pL9
|
||||
FgpIgjjhC9B+hToo9uuLC2Ox58TA+7l1sR4JG0XCNW0Z+5swBnWyrlt/ZwWxFqoB
|
||||
oxYE/j3yxh9TmgHv54/j2ZzU8tiJHW01AGlbbxo=
|
||||
=cWkh
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -4,6 +4,10 @@ from(bucket: "${bucket}")
|
|||
<% values = values if isinstance(values, list) else [values] %>\
|
||||
|> filter(fn: (r) => ${' or '.join(f'r["{key}"] == "{value}"' for value in values)})
|
||||
% endfor
|
||||
% for exist in exists:
|
||||
|> filter(fn: (r) => exists r["${exist}"]) // WTF
|
||||
% endfor
|
||||
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) // aggregate early for best performance
|
||||
% if minimum:
|
||||
|> filter(fn: (r) => r._value > ${minimum})
|
||||
% endif
|
||||
|
@ -13,7 +17,6 @@ from(bucket: "${bucket}")
|
|||
% if boolean_to_int:
|
||||
|> map(fn: (r) => ({r with _value: if r._value == true then 1 else 0 }))
|
||||
% endif
|
||||
|> aggregateWindow(every: duration(v: int(v: v.windowPeriod)*${resolution}), fn: mean, createEmpty: false)
|
||||
% if negative:
|
||||
|> map(fn: (r) => ({r with _value: r._value * - 1.0}))
|
||||
% endif
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
{
|
||||
'usage': {
|
||||
'stacked': False,
|
||||
'stacked': True,
|
||||
'queries': {
|
||||
'usage': {
|
||||
'filters': {
|
||||
'_measurement': 'cpu',
|
||||
'cpu': 'cpu-total',
|
||||
'_field': [
|
||||
'usage_guest',
|
||||
'usage_guest_nice',
|
||||
'usage_iowait',
|
||||
'usage_irq',
|
||||
'usage_nice',
|
||||
'usage_softirq',
|
||||
'usage_steal',
|
||||
'usage_system',
|
||||
'usage_user',
|
||||
],
|
||||
|
@ -16,7 +22,12 @@
|
|||
},
|
||||
},
|
||||
'min': 0,
|
||||
'max': 100,
|
||||
'soft_max': 3,
|
||||
'unit': 'percent',
|
||||
'tooltip': 'multi',
|
||||
'legend': {
|
||||
'displayMode': 'hidden',
|
||||
},
|
||||
},
|
||||
'load': {
|
||||
'stacked': False,
|
||||
|
@ -33,5 +44,40 @@
|
|||
'function': 'mean',
|
||||
},
|
||||
},
|
||||
'min': 0,
|
||||
'soft_max': 3,
|
||||
'unit': 'percent',
|
||||
'tooltip': 'multi',
|
||||
'legend': {
|
||||
'displayMode': 'hidden',
|
||||
},
|
||||
},
|
||||
'pressure_stall': {
|
||||
'queries': {
|
||||
'pressure_stall': {
|
||||
'filters': {
|
||||
'_measurement': 'pressure_stall',
|
||||
'resource': [
|
||||
'cpu',
|
||||
'io',
|
||||
'memory',
|
||||
],
|
||||
'type': [
|
||||
'some',
|
||||
],
|
||||
'_field': [
|
||||
'avg10',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'min': 0,
|
||||
'soft_max': 3,
|
||||
'display_name': '__field.labels.resource',
|
||||
'unit': 'percent',
|
||||
'tooltip': 'multi',
|
||||
'legend': {
|
||||
'displayMode': 'hidden',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,11 +9,15 @@
|
|||
'read_bytes',
|
||||
],
|
||||
},
|
||||
'exists': [
|
||||
'ID_PART_ENTRY_NUMBER',
|
||||
],
|
||||
'function': 'derivative',
|
||||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'display_name': '__field.labels.name'
|
||||
'unit': 'Bps',
|
||||
'display_name': '__field.labels.name',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
'write': {
|
||||
'stacked': True,
|
||||
|
@ -25,10 +29,14 @@
|
|||
'write_bytes',
|
||||
],
|
||||
},
|
||||
'exists': [
|
||||
'ID_PART_ENTRY_NUMBER',
|
||||
],
|
||||
'function': 'derivative',
|
||||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'display_name': '__field.labels.name'
|
||||
'unit': 'Bps',
|
||||
'display_name': '__field.labels.name',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
'min': 0,
|
||||
'unit': 'bytes',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
'root_inodes': {
|
||||
'stacked': True,
|
||||
|
@ -33,5 +34,6 @@
|
|||
},
|
||||
},
|
||||
'min': 0,
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
'swp': {
|
||||
'stacked': True,
|
||||
|
@ -32,5 +33,6 @@
|
|||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
'function': 'derivative',
|
||||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'display_name': '__field.labels.interface'
|
||||
'unit': 'Bps',
|
||||
'display_name': '__field.labels.interface',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
'out': {
|
||||
'stacked': True,
|
||||
|
@ -28,7 +29,8 @@
|
|||
'function': 'derivative',
|
||||
},
|
||||
},
|
||||
'unit': 'decbytes',
|
||||
'display_name': '__field.labels.interface'
|
||||
'unit': 'Bps',
|
||||
'display_name': '__field.labels.interface',
|
||||
'tooltip': 'multi',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
'length',
|
||||
],
|
||||
},
|
||||
'function': 'mean',
|
||||
'function': 'max',
|
||||
},
|
||||
},
|
||||
'display_name': '__field.labels.queue'
|
||||
|
@ -24,7 +24,7 @@
|
|||
'size',
|
||||
],
|
||||
},
|
||||
'function': 'mean',
|
||||
'function': 'max',
|
||||
},
|
||||
},
|
||||
'display_name': '__field.labels.queue'
|
||||
|
@ -39,7 +39,7 @@
|
|||
'age',
|
||||
],
|
||||
},
|
||||
'function': 'mean',
|
||||
'function': 'max',
|
||||
},
|
||||
},
|
||||
'display_name': '__field.labels.queue'
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
'process_cpu': {
|
||||
'stacked': True,
|
||||
'queries': {
|
||||
'cpu': {
|
||||
'filters': {
|
||||
'_measurement': 'procstat',
|
||||
'_field': [
|
||||
'cpu_usage',
|
||||
],
|
||||
},
|
||||
'minimum': 1,
|
||||
'resolution': 2,
|
||||
},
|
||||
},
|
||||
'unit': 'percent',
|
||||
'display_name': '__field.labels.process_name',
|
||||
'legend': {
|
||||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'mean',
|
||||
'max',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
48
data/grafana/rows/proc_cpu_ram.py
Normal file
48
data/grafana/rows/proc_cpu_ram.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
'cpu': {
|
||||
'stacked': True,
|
||||
'queries': {
|
||||
'cpu': {
|
||||
'filters': {
|
||||
'_measurement': 'procstat',
|
||||
'_field': [
|
||||
'cpu_usage',
|
||||
],
|
||||
},
|
||||
'minimum': 0.2,
|
||||
},
|
||||
},
|
||||
'unit': 'percent',
|
||||
'display_name': '__field.labels.process_name',
|
||||
'legend': {
|
||||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'last',
|
||||
],
|
||||
},
|
||||
},
|
||||
'ram': {
|
||||
'stacked': True,
|
||||
'queries': {
|
||||
'ram': {
|
||||
'filters': {
|
||||
'_measurement': 'procstat',
|
||||
'_field': [
|
||||
'memory_rss',
|
||||
],
|
||||
},
|
||||
'minimum': 10*(10**6),
|
||||
},
|
||||
},
|
||||
'unit': 'bytes',
|
||||
'display_name': '__field.labels.process_name',
|
||||
'legend': {
|
||||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'last',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
|
@ -19,8 +19,7 @@
|
|||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'mean',
|
||||
'max',
|
||||
'last',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -44,8 +43,7 @@
|
|||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'mean',
|
||||
'max',
|
||||
'last',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
'process_ram': {
|
||||
'stacked': True,
|
||||
'queries': {
|
||||
'ram': {
|
||||
'filters': {
|
||||
'_measurement': 'procstat',
|
||||
'_field': [
|
||||
'memory_rss',
|
||||
],
|
||||
},
|
||||
'minimum': 10*(10**6),
|
||||
'resolution': 2,
|
||||
},
|
||||
},
|
||||
'unit': 'bytes',
|
||||
'display_name': '__field.labels.process_name',
|
||||
'legend': {
|
||||
'displayMode': 'table',
|
||||
'placement': 'right',
|
||||
'calcs': [
|
||||
'mean',
|
||||
'max',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
|
@ -80,6 +80,6 @@
|
|||
'negative': True,
|
||||
},
|
||||
},
|
||||
'unit': 'bytes',
|
||||
'unit': 'Bps',
|
||||
},
|
||||
}
|
||||
|
|
28
data/grafana/vhost.conf
Normal file
28
data/grafana/vhost.conf
Normal file
|
@ -0,0 +1,28 @@
|
|||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name ${server_name};
|
||||
|
||||
ssl_certificate /var/lib/dehydrated/certs/${server_name}/fullchain.pem;
|
||||
ssl_certificate_key /var/lib/dehydrated/certs/${server_name}/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://127.0.0.1:8300/;
|
||||
}
|
||||
|
||||
# Proxy Grafana Live WebSocket connections.
|
||||
location /api/live {
|
||||
rewrite ^/(.*) /$1 break;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://127.0.0.1:8300/;
|
||||
}
|
||||
}
|
20
data/steam-chat-viewer/vhost.conf
Normal file
20
data/steam-chat-viewer/vhost.conf
Normal file
|
@ -0,0 +1,20 @@
|
|||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name ${server_name};
|
||||
|
||||
ssl_certificate /var/lib/dehydrated/certs/${server_name}/fullchain.pem;
|
||||
ssl_certificate_key /var/lib/dehydrated/certs/${server_name}/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass http://127.0.0.1:4001;
|
||||
}
|
||||
|
||||
location /steamuserimages/ {
|
||||
root /var/lib/steam_chat_logger/steamuserimages;
|
||||
rewrite ^/steamuserimages(.*)$ $1 break;
|
||||
autoindex on;
|
||||
}
|
||||
}
|
20
groups/os/debian-12.py
Normal file
20
groups/os/debian-12.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
'supergroups': [
|
||||
'debian',
|
||||
],
|
||||
'metadata': {
|
||||
'apt': {
|
||||
'sources': {
|
||||
'deb http://security.debian.org/ {release}-security main contrib non-free',
|
||||
},
|
||||
},
|
||||
'php': {
|
||||
'version': '8.1',
|
||||
},
|
||||
'postgresql': {
|
||||
'version': '14',
|
||||
},
|
||||
'os_release': 'bookworm',
|
||||
},
|
||||
'os_version': (12,),
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
'bundles': [
|
||||
'hostname',
|
||||
'hosts',
|
||||
'htop',
|
||||
'locale',
|
||||
'network',
|
||||
'ssh',
|
||||
|
@ -30,9 +31,15 @@
|
|||
],
|
||||
},
|
||||
'users': {
|
||||
'root': {
|
||||
'ckn': {
|
||||
'shell': '/usr/bin/zsh',
|
||||
'authorized_keys': {
|
||||
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEU1l2ijW3ZqzFGZcdWg2ESgTGehdNfBTfafxsjWvWdS mwiegand@macbook',
|
||||
},
|
||||
},
|
||||
},
|
||||
'sudoers': {
|
||||
'ckn': {'ALL'},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
def node_apply_start(repo, node, interactive=False, **kwargs):
|
||||
def node_apply_start(repo, node, **kwargs):
|
||||
repo.libs.wol.wake(node)
|
||||
|
||||
def node_run_start(repo, node, cmd, **kwargs):
|
||||
repo.libs.wol.wake(node)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
'monitored',
|
||||
],
|
||||
'bundles': [
|
||||
'grub',
|
||||
'smartctl',
|
||||
'wol-sleeper',
|
||||
'zfs',
|
||||
|
@ -17,10 +18,10 @@
|
|||
'id': '9cf52515-63a1-4659-a8ec-6c3c881727e5',
|
||||
'network': {
|
||||
'internal': {
|
||||
'interface': 'enp1s0',
|
||||
'interface': 'enp0s31f6',
|
||||
'ipv4': '10.0.0.5/24',
|
||||
'gateway4': '10.0.0.1',
|
||||
'mac': 'd8:cb:8a:e7:be:c6',
|
||||
'mac': '4c:cc:6a:d5:96:f8',
|
||||
},
|
||||
},
|
||||
'backup-server': {
|
||||
|
@ -55,6 +56,12 @@
|
|||
],
|
||||
},
|
||||
},
|
||||
'auto_snapshots': {
|
||||
'hourly': 1,
|
||||
'daily': 7,
|
||||
'weekly': 4,
|
||||
'monthly': 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
'zfs',
|
||||
],
|
||||
'metadata': {
|
||||
'FIXME_dont_touch_sshd': True,
|
||||
'id': '34199b24-4621-42f4-85ae-ec354f9c43e6',
|
||||
'network': {
|
||||
'internal': {
|
||||
|
|
|
@ -16,17 +16,19 @@
|
|||
'build-agent',
|
||||
'crystal',
|
||||
'gitea',
|
||||
'gollum',
|
||||
# 'gollum',
|
||||
'grafana',
|
||||
'icinga2',
|
||||
'icingadb',
|
||||
'icingaweb2',
|
||||
'influxdb2',
|
||||
'mirror',
|
||||
'mosquitto',
|
||||
'postgresql',
|
||||
'redis',
|
||||
'smartctl',
|
||||
'steam-chat-logger',
|
||||
'steam-chat-viewer',
|
||||
'systemd-swap',
|
||||
'raspberrymatic-cert',
|
||||
'tasmota-charge',
|
||||
'wireguard',
|
||||
|
@ -37,7 +39,7 @@
|
|||
'id': 'af96709e-b13f-4965-a588-ef2cd476437a',
|
||||
'network': {
|
||||
'internal': {
|
||||
'interface': 'enp1s0f0',
|
||||
'interface': 'enp42s0',
|
||||
'ipv4': '10.0.0.2/24',
|
||||
'gateway4': '10.0.0.1',
|
||||
},
|
||||
|
@ -57,8 +59,8 @@
|
|||
'download_server': 'netcup.mails',
|
||||
},
|
||||
'gitea': {
|
||||
'version': '1.16.2',
|
||||
'sha256': 'ec9b01d119cfe47df44d580c1d321132ce054ff139b05b0a35da91268ca2bcbe',
|
||||
'version': '1.16.5',
|
||||
'sha256': 'c0fb4107dc4debf08e6e27fd3383e06dc232ccb410123179c7ae8d7cec60765f',
|
||||
'domain': 'git.sublimity.de',
|
||||
},
|
||||
'gollum': {
|
||||
|
@ -90,7 +92,7 @@
|
|||
},
|
||||
'nextcloud': {
|
||||
'hostname': 'cloud.sublimity.de',
|
||||
'version': '23.0.2',
|
||||
'version': '24.0.4',
|
||||
},
|
||||
'nextcloud-picsort': {
|
||||
'ckn': {
|
||||
|
@ -103,10 +105,22 @@
|
|||
'domain': 'homematic.ckn.li',
|
||||
'node': 'home.homematic',
|
||||
},
|
||||
'steam_chat_logger': {
|
||||
'STEAM_USERNAME': 'snake_452',
|
||||
'STEAM_ID': 'STEAM_0:0:12376499',
|
||||
'STEAM_PASSWORD': '!decrypt:encrypt$gAAAAABiUzERrXVNxzDaDW_4MgEmPtXkMHlTiz5uqCbu-22-2yKHRHMKvuGqAygpGbnwZucZcmZMox9KM89a6qlVKlE1ZPizTA==',
|
||||
'IMAP_HOST': 'mail.sublimity.de',
|
||||
'IMAP_USER': 'i@ckn.li',
|
||||
'IMAP_PASSWORD': '!decrypt:encrypt$gAAAAABiUzcTVRL-Xb4RDjcwciZawYlmOa9Qy_hKz6sVWDlwZqUFLGRD8ERWoFCOWCM22Sq73Gc4nFuAblBB6wpbH5YEltLA6hmROGKpOFhI63ESLFwNgbY=',
|
||||
},
|
||||
'steam-chat-viewer': {
|
||||
'hostname': 'steam-chats.ckn.li',
|
||||
},
|
||||
'systemd-swap': 4_000_000_000,
|
||||
'tasmota-charge': {
|
||||
'phone': {
|
||||
'ip': '10.0.0.166',
|
||||
'user': 'u0_q194',
|
||||
'ip': '10.0.0.175',
|
||||
'user': 'u0_a233',
|
||||
'password': 'november',
|
||||
},
|
||||
'plug': {
|
||||
|
@ -116,8 +130,9 @@
|
|||
},
|
||||
},
|
||||
'vm': {
|
||||
'cores': 2,
|
||||
'ram': 16192,
|
||||
'cores': 16,
|
||||
'threads': 32,
|
||||
'ram': 49152,
|
||||
},
|
||||
'wireguard': {
|
||||
'my_ip': '172.30.0.2/32',
|
||||
|
@ -132,6 +147,10 @@
|
|||
},
|
||||
},
|
||||
'zfs': {
|
||||
'zfs_arc_max_percent': 80,
|
||||
'storage_classes': {
|
||||
'ssd': 'ssd',
|
||||
},
|
||||
'pools': {
|
||||
'tank': {
|
||||
'type': 'mirror',
|
||||
|
@ -140,6 +159,17 @@
|
|||
'/dev/disk/by-partlabel/zfs-data-2',
|
||||
],
|
||||
},
|
||||
'ssd': {
|
||||
'devices': [
|
||||
'/dev/disk/by-id/nvme-SAMSUNG_MZVL22T0HBLB-00B00_S677NF0RA01551-part3',
|
||||
],
|
||||
},
|
||||
},
|
||||
'datasets': {
|
||||
'ssd/nextcloud-appdata': {
|
||||
'mountpoint': '/var/lib/nextcloud/appdata_oci6dw1woodz',
|
||||
'backup': False,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
'wpa-supplicant',
|
||||
],
|
||||
'metadata': {
|
||||
'FIXME_dont_touch_sshd': True,
|
||||
|
||||
'id': 'dd521b8a-dc03-43f5-b29f-068f948ba3b8',
|
||||
'network': {
|
||||
'internal': {
|
||||
|
|
|
@ -54,11 +54,6 @@
|
|||
'device': '/dev/disk/by-id/ata-TOSHIBA_MG06ACA10TE_61C0A1B1FKQE',
|
||||
},
|
||||
},
|
||||
'smartctl': {
|
||||
'/dev/disk/by-id/ata-TOSHIBA_MG06ACA10TE_61C0A1B1FKQE': {
|
||||
'apm': 1,
|
||||
},
|
||||
},
|
||||
'zfs': {
|
||||
'pools': {
|
||||
'tank': {
|
||||
|
@ -67,6 +62,12 @@
|
|||
],
|
||||
},
|
||||
},
|
||||
'auto_snapshots': {
|
||||
'hourly': 1,
|
||||
'daily': 1,
|
||||
'weekly': 4,
|
||||
'monthly': 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue