122 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from ipaddress import ip_interface
 | |
| 
 | |
| defaults = {
 | |
|     'apt': {
 | |
|         'packages': {
 | |
|             'rsync': {},
 | |
|         },
 | |
|     },
 | |
|     'users': {
 | |
|         'backup-receiver': {
 | |
|             'authorized_keys': set(),
 | |
|         },
 | |
|     },
 | |
|     'sudoers': {
 | |
|         'backup-receiver': {
 | |
|             '/usr/bin/rsync',
 | |
|             '/sbin/zfs',
 | |
|         },
 | |
|     },
 | |
|     'zfs': {
 | |
|         'datasets': {
 | |
|             'tank': {
 | |
|                 'recordsize': "1048576",
 | |
|             },
 | |
|         },
 | |
|     },
 | |
| }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'zfs/datasets'
 | |
| )
 | |
| def zfs(metadata):
 | |
|     datasets = {}
 | |
| 
 | |
|     for other_node in repo.nodes:
 | |
|         if (
 | |
|             not other_node.dummy and
 | |
|             other_node.has_bundle('backup') and
 | |
|             other_node.metadata.get('backup/server') == node.name
 | |
|         ):
 | |
|             id = other_node.metadata.get('id')
 | |
|             base_dataset = f'tank/{id}'
 | |
| 
 | |
|             # container
 | |
|             datasets[base_dataset] = {
 | |
|                 'mountpoint': None,
 | |
|                 'readonly': 'on',
 | |
|                 'compression': 'lz4',
 | |
|                 'com.sun:auto-snapshot': 'false',
 | |
|                 'backup': False,
 | |
|             }
 | |
| 
 | |
|             # for rsync backups
 | |
|             datasets[f'{base_dataset}/fs'] = {
 | |
|                 'mountpoint': f"/mnt/backups/{id}",
 | |
|                 'readonly': 'off',
 | |
|                 'compression': 'lz4',
 | |
|                 'com.sun:auto-snapshot': 'true',
 | |
|                 'backup': False,
 | |
|             }
 | |
| 
 | |
|             # for zfs send/recv
 | |
|             if other_node.has_bundle('zfs'):
 | |
| 
 | |
|                 # base datasets for each tank
 | |
|                 for pool in other_node.metadata.get('zfs/pools'):
 | |
|                     datasets[f'{base_dataset}/{pool}'] = {
 | |
|                         'mountpoint': None,
 | |
|                         'readonly': 'on',
 | |
|                         'compression': 'lz4',
 | |
|                         'com.sun:auto-snapshot': 'false',
 | |
|                         'backup': False,
 | |
|                     }
 | |
| 
 | |
|                 # actual datasets
 | |
|                 for path in other_node.metadata.get('backup/paths'):
 | |
|                     for dataset, config in other_node.metadata.get('zfs/datasets').items():
 | |
|                         if path == config.get('mountpoint'):
 | |
|                             datasets[f'{base_dataset}/{dataset}'] = {
 | |
|                                 'mountpoint': None,
 | |
|                                 'readonly': 'on',
 | |
|                                 'compression': 'lz4',
 | |
|                                 'com.sun:auto-snapshot': 'false',
 | |
|                                 'backup': False,
 | |
|                             }
 | |
|                             continue
 | |
| 
 | |
|     return {
 | |
|         'zfs': {
 | |
|             'datasets': datasets,
 | |
|         },
 | |
|     }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'dns',
 | |
| )
 | |
| def dns(metadata):
 | |
|     return {
 | |
|         'dns': {
 | |
|             metadata.get('backup-server/hostname'): repo.libs.ip.get_a_records(metadata),
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
| @metadata_reactor.provides(
 | |
|     'users/backup-receiver/authorized_keys'
 | |
| )
 | |
| def backup_authorized_keys(metadata):
 | |
|     return {
 | |
|         'users': {
 | |
|             'backup-receiver': {
 | |
|                 'authorized_keys': {
 | |
|                     other_node.metadata.get('users/root/pubkey')
 | |
|                         for other_node in repo.nodes
 | |
|                         if other_node.has_bundle('backup')
 | |
|                         and other_node.metadata.get('backup/server') == node.name
 | |
|                 },
 | |
|             },
 | |
|         },
 | |
|     }
 |