migrate to bundlewrap 5
- pin bundlewrap ~=5.0 - rewrite non-reading and KeyError-driven metadata reactors per https://docs.bundlewrap.org/guide/migrate_45/ (defaults / metadata.get paths / MetadataUnavailable) - rename custom Download item methods (cdict/sdict/get_auto_deps -> expected_state/actual_state/get_auto_attrs) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e99fd4b1a4
commit
186d5039af
13 changed files with 93 additions and 171 deletions
|
|
@ -5,6 +5,7 @@ defaults = {
|
||||||
'installed': False,
|
'installed': False,
|
||||||
},
|
},
|
||||||
'ca-certificates': {},
|
'ca-certificates': {},
|
||||||
|
'unattended-upgrades': {},
|
||||||
},
|
},
|
||||||
'config': {
|
'config': {
|
||||||
'DPkg': {
|
'DPkg': {
|
||||||
|
|
@ -22,6 +23,10 @@ defaults = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'APT': {
|
'APT': {
|
||||||
|
'Periodic': {
|
||||||
|
'Update-Package-Lists': '1',
|
||||||
|
'Unattended-Upgrade': '1',
|
||||||
|
},
|
||||||
'NeverAutoRemove': {
|
'NeverAutoRemove': {
|
||||||
'^firmware-linux.*',
|
'^firmware-linux.*',
|
||||||
'^linux-firmware$',
|
'^linux-firmware$',
|
||||||
|
|
@ -49,6 +54,11 @@ defaults = {
|
||||||
'Error-Mode': 'any',
|
'Error-Mode': 'any',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'Unattended-Upgrade': {
|
||||||
|
'Origins-Pattern': {
|
||||||
|
"origin=*",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'sources': {},
|
'sources': {},
|
||||||
},
|
},
|
||||||
|
|
@ -107,33 +117,6 @@ def signed_by(metadata):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'apt/config',
|
|
||||||
'apt/packages',
|
|
||||||
)
|
|
||||||
def unattended_upgrades(metadata):
|
|
||||||
return {
|
|
||||||
'apt': {
|
|
||||||
'config': {
|
|
||||||
'APT': {
|
|
||||||
'Periodic': {
|
|
||||||
'Update-Package-Lists': '1',
|
|
||||||
'Unattended-Upgrade': '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'Unattended-Upgrade': {
|
|
||||||
'Origins-Pattern': {
|
|
||||||
"origin=*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'packages': {
|
|
||||||
'unattended-upgrades': {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# @metadata_reactor.provides(
|
# @metadata_reactor.provides(
|
||||||
# 'apt/config',
|
# 'apt/config',
|
||||||
# 'apt/list_changes',
|
# 'apt/list_changes',
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ defaults = {
|
||||||
'needs': {
|
'needs': {
|
||||||
'zfs_dataset:tank/downloads'
|
'zfs_dataset:tank/downloads'
|
||||||
},
|
},
|
||||||
|
'authorized_users': {
|
||||||
|
f'build-server@{other_node.name}': {}
|
||||||
|
for other_node in repo.nodes
|
||||||
|
if other_node.has_bundle('build-server')
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'zfs': {
|
'zfs': {
|
||||||
|
|
@ -14,14 +19,6 @@ defaults = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'systemd-mount'
|
|
||||||
)
|
|
||||||
def mount_certs(metadata):
|
|
||||||
return {
|
|
||||||
'systemd-mount': {
|
'systemd-mount': {
|
||||||
'/var/lib/downloads_nginx': {
|
'/var/lib/downloads_nginx': {
|
||||||
'source': '/var/lib/downloads',
|
'source': '/var/lib/downloads',
|
||||||
|
|
@ -47,20 +44,3 @@ def nginx(metadata):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'users/downloads/authorized_users',
|
|
||||||
)
|
|
||||||
def ssh_keys(metadata):
|
|
||||||
return {
|
|
||||||
'users': {
|
|
||||||
'downloads': {
|
|
||||||
'authorized_users': {
|
|
||||||
f'build-server@{other_node.name}': {}
|
|
||||||
for other_node in repo.nodes
|
|
||||||
if other_node.has_bundle('build-server')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ def units(metadata):
|
||||||
'Service': {
|
'Service': {
|
||||||
'Environment': {
|
'Environment': {
|
||||||
f'{k}={v}'
|
f'{k}={v}'
|
||||||
for k, v in conf.get('env', {}).items()
|
for k, v in metadata.get(f'flask/{name}/env', {}).items()
|
||||||
},
|
},
|
||||||
'User': conf['user'],
|
'User': metadata.get(f'flask/{name}/user'),
|
||||||
'Group': conf['group'],
|
'Group': metadata.get(f'flask/{name}/group'),
|
||||||
'ExecStart': f"/opt/{name}/venv/bin/gunicorn -w {conf['workers']} -b 127.0.0.1:{conf['port']} --timeout {conf['timeout']} {conf['app_module']}:app"
|
'ExecStart': f"/opt/{name}/venv/bin/gunicorn -w {metadata.get(f'flask/{name}/workers')} -b 127.0.0.1:{metadata.get(f'flask/{name}/port')} --timeout {metadata.get(f'flask/{name}/timeout')} {metadata.get(f'flask/{name}/app_module')}:app"
|
||||||
},
|
},
|
||||||
'Install': {
|
'Install': {
|
||||||
'WantedBy': {
|
'WantedBy': {
|
||||||
|
|
@ -55,7 +55,7 @@ def units(metadata):
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for name, conf in metadata.get('flask').items()
|
for name in metadata.get('flask')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,17 @@ defaults = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.has_bundle('zfs'):
|
||||||
|
defaults['zfs'] = {
|
||||||
|
'datasets': {
|
||||||
|
'tank/influxdb': {
|
||||||
|
'mountpoint': '/var/lib/influxdb',
|
||||||
|
'recordsize': '8192',
|
||||||
|
'atime': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'influxdb/password',
|
'influxdb/password',
|
||||||
'influxdb/admin_token',
|
'influxdb/admin_token',
|
||||||
|
|
@ -52,26 +63,6 @@ def admin_password(metadata):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'zfs/datasets',
|
|
||||||
)
|
|
||||||
def zfs(metadata):
|
|
||||||
if not node.has_bundle('zfs'):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'zfs': {
|
|
||||||
'datasets': {
|
|
||||||
'tank/influxdb': {
|
|
||||||
'mountpoint': '/var/lib/influxdb',
|
|
||||||
'recordsize': '8192',
|
|
||||||
'atime': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'dns',
|
'dns',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ def user(metadata):
|
||||||
'sshmon': {
|
'sshmon': {
|
||||||
conf['vars.command']
|
conf['vars.command']
|
||||||
for conf in metadata.get('monitoring/services').values()
|
for conf in metadata.get('monitoring/services').values()
|
||||||
if conf['check_command'] == 'sshmon'
|
if conf.get('check_command') == 'sshmon'
|
||||||
and conf.get('vars.sudo', None)
|
and conf.get('vars.sudo', None)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,12 @@ def dhcp(metadata):
|
||||||
'modules-load',
|
'modules-load',
|
||||||
)
|
)
|
||||||
def units(metadata):
|
def units(metadata):
|
||||||
|
networks = metadata.get('network', {})
|
||||||
if node.has_bundle('systemd-networkd'):
|
if node.has_bundle('systemd-networkd'):
|
||||||
units = {}
|
units = {}
|
||||||
modules_load = set()
|
modules_load = set()
|
||||||
|
|
||||||
for network_name, network_conf in metadata.get('network').items():
|
for network_name, network_conf in networks.items():
|
||||||
interface_type = network_conf.get('type', None)
|
interface_type = network_conf.get('type', None)
|
||||||
|
|
||||||
# network
|
# network
|
||||||
|
|
@ -116,6 +117,7 @@ def units(metadata):
|
||||||
'systemd/units',
|
'systemd/units',
|
||||||
)
|
)
|
||||||
def queuing_disciplines(metadata):
|
def queuing_disciplines(metadata):
|
||||||
|
networks = metadata.get('network', {})
|
||||||
if node.has_bundle('systemd-networkd'):
|
if node.has_bundle('systemd-networkd'):
|
||||||
return {
|
return {
|
||||||
'systemd': {
|
'systemd': {
|
||||||
|
|
@ -136,7 +138,7 @@ def queuing_disciplines(metadata):
|
||||||
'WantedBy': 'network-online.target',
|
'WantedBy': 'network-online.target',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for network_name, network_conf in metadata.get('network').items()
|
for network_name, network_conf in networks.items()
|
||||||
if 'qdisc' in network_conf
|
if 'qdisc' in network_conf
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,17 @@ defaults = {
|
||||||
'grafana_rows': set(),
|
'grafana_rows': set(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.has_bundle('zfs'):
|
||||||
|
defaults['zfs'] = {
|
||||||
|
'datasets': {
|
||||||
|
'tank/postgresql': {
|
||||||
|
'mountpoint': '/var/lib/postgresql',
|
||||||
|
'recordsize': '8192',
|
||||||
|
'atime': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'postgresql/conf',
|
'postgresql/conf',
|
||||||
|
|
@ -77,26 +88,6 @@ def apt(metadata):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'zfs/datasets',
|
|
||||||
)
|
|
||||||
def zfs(metadata):
|
|
||||||
if not node.has_bundle('zfs'):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'zfs': {
|
|
||||||
'datasets': {
|
|
||||||
'tank/postgresql': {
|
|
||||||
'mountpoint': '/var/lib/postgresql',
|
|
||||||
'recordsize': '8192',
|
|
||||||
'atime': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'telegraf/inputs/postgresql/default',
|
'telegraf/inputs/postgresql/default',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,19 @@ defaults = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.has_bundle('zfs'):
|
||||||
|
defaults['zfs'] = {
|
||||||
|
'kernel_params': {
|
||||||
|
'zfs_txg_timeout': 300,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'telegraf/agent',
|
'telegraf/agent',
|
||||||
)
|
)
|
||||||
def telegraf(metadata):
|
def telegraf(metadata):
|
||||||
|
metadata.get('telegraf/agent') # only override if telegraf bundle is present
|
||||||
return {
|
return {
|
||||||
'telegraf': {
|
'telegraf': {
|
||||||
'agent': {
|
'agent': {
|
||||||
|
|
@ -19,20 +27,3 @@ def telegraf(metadata):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'zfs/kernel_params',
|
|
||||||
'zfs/datasets',
|
|
||||||
)
|
|
||||||
def zfs(metadata):
|
|
||||||
if not node.has_bundle('zfs'):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'zfs': {
|
|
||||||
'kernel_params': {
|
|
||||||
'zfs_txg_timeout': 300,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
defaults = {
|
||||||
|
'systemd-timers': {
|
||||||
|
'raspberrymatic-cert': {
|
||||||
|
'command': '/opt/raspberrymatic-cert',
|
||||||
|
'when': 'daily',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'letsencrypt/domains',
|
'letsencrypt/domains',
|
||||||
)
|
)
|
||||||
|
|
@ -11,17 +21,3 @@ def letsencrypt(metadata):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'systemd-timers/raspberrymatic-cert',
|
|
||||||
)
|
|
||||||
def systemd_timers(metadata):
|
|
||||||
return {
|
|
||||||
'systemd-timers': {
|
|
||||||
'raspberrymatic-cert': {
|
|
||||||
'command': '/opt/raspberrymatic-cert',
|
|
||||||
'when': 'daily',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@ defaults = {
|
||||||
# needed by crystal plugins:
|
# needed by crystal plugins:
|
||||||
'libgc-dev': {},
|
'libgc-dev': {},
|
||||||
'libevent-dev': {},
|
'libevent-dev': {},
|
||||||
|
(
|
||||||
|
'libpcre2-8-0'
|
||||||
|
if node.os == 'debian' and node.os_version >= (13,)
|
||||||
|
else 'libpcre3'
|
||||||
|
): {},
|
||||||
},
|
},
|
||||||
'sources': {
|
'sources': {
|
||||||
'influxdata': {
|
'influxdata': {
|
||||||
|
|
@ -148,20 +153,3 @@ def influxdb(metadata):
|
||||||
|
|
||||||
|
|
||||||
# crystal based (procio, pressure_stall):
|
# crystal based (procio, pressure_stall):
|
||||||
@metadata_reactor.provides(
|
|
||||||
'apt/packages/libpcre2-8-0',
|
|
||||||
'apt/packages/libpcre3',
|
|
||||||
)
|
|
||||||
def libpcre(metadata):
|
|
||||||
if node.os == 'debian' and node.os_version >= (13,):
|
|
||||||
libpcre_package = 'libpcre2-8-0'
|
|
||||||
else:
|
|
||||||
libpcre_package = 'libpcre3'
|
|
||||||
|
|
||||||
return {
|
|
||||||
'apt': {
|
|
||||||
'packages': {
|
|
||||||
libpcre_package: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -112,20 +112,18 @@ def systemd_networkd_netdevs(metadata):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for peer, config in {
|
for kind in ('s2s', 'clients'):
|
||||||
**metadata.get('wireguard/s2s'),
|
for peer in metadata.get(f'wireguard/{kind}'):
|
||||||
**metadata.get('wireguard/clients'),
|
peer_id = metadata.get(f'wireguard/{kind}/{peer}/peer_id')
|
||||||
}.items():
|
netdev[f'WireGuardPeer#{peer}'] = {
|
||||||
netdev.update({
|
'PublicKey': repo.libs.wireguard.pubkey(peer_id),
|
||||||
f'WireGuardPeer#{peer}': {
|
'PresharedKey': repo.libs.wireguard.psk(peer_id, metadata.get('id')),
|
||||||
'PublicKey': repo.libs.wireguard.pubkey(config['peer_id']),
|
'AllowedIPs': ', '.join(metadata.get(f'wireguard/{kind}/{peer}/allowed_ips', [])),
|
||||||
'PresharedKey': repo.libs.wireguard.psk(config['peer_id'], metadata.get('id')),
|
|
||||||
'AllowedIPs': ', '.join(config.get('allowed_ips', [])),
|
|
||||||
'PersistentKeepalive': 30,
|
'PersistentKeepalive': 30,
|
||||||
}
|
}
|
||||||
})
|
endpoint = metadata.get(f'wireguard/{kind}/{peer}/endpoint', None)
|
||||||
if config.get('endpoint'):
|
if endpoint:
|
||||||
netdev[f'WireGuardPeer#{peer}']['Endpoint'] = config['endpoint']
|
netdev[f'WireGuardPeer#{peer}']['Endpoint'] = endpoint
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'systemd': {
|
'systemd': {
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ class Download(Item):
|
||||||
url=quote(self.attributes['url'])
|
url=quote(self.attributes['url'])
|
||||||
))
|
))
|
||||||
|
|
||||||
def cdict(self):
|
@property
|
||||||
|
def expected_state(self):
|
||||||
"""This is how the world should be"""
|
"""This is how the world should be"""
|
||||||
cdict = {
|
cdict = {
|
||||||
'type': 'download',
|
'type': 'download',
|
||||||
|
|
@ -85,7 +86,8 @@ class Download(Item):
|
||||||
|
|
||||||
return cdict
|
return cdict
|
||||||
|
|
||||||
def sdict(self):
|
@property
|
||||||
|
def actual_state(self):
|
||||||
"""This is how the world is right now"""
|
"""This is how the world is right now"""
|
||||||
path_info = PathInfo(self.node, self.name)
|
path_info = PathInfo(self.node, self.name)
|
||||||
if not path_info.exists:
|
if not path_info.exists:
|
||||||
|
|
@ -135,10 +137,10 @@ class Download(Item):
|
||||||
item=item_id,
|
item=item_id,
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_auto_deps(self, items):
|
def get_auto_attrs(self, items):
|
||||||
deps = []
|
deps = []
|
||||||
for item in items:
|
for item in items:
|
||||||
# debian TODO: add other package manager
|
# debian TODO: add other package manager
|
||||||
if item.ITEM_TYPE_NAME == 'pkg_apt' and item.name == 'curl':
|
if item.ITEM_TYPE_NAME == 'pkg_apt' and item.name == 'curl':
|
||||||
deps.append(item.id)
|
deps.append(item.id)
|
||||||
return deps
|
return {'needs': deps}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
bundlewrap ~=4.0, >=4.24
|
bundlewrap ~=5.0, >=5.0.3
|
||||||
pycryptodome
|
pycryptodome
|
||||||
PyNaCl
|
PyNaCl
|
||||||
PyYAML
|
PyYAML
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue