105 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from re import match
 | |
| from glob import glob
 | |
| from os.path import join, basename, exists
 | |
| 
 | |
| 
 | |
| def format_variables(node, string):
 | |
|     return string.format(
 | |
|         codename=node.metadata.get('os_codename'),
 | |
|         version=node.os_version[0],
 | |
|     )
 | |
| 
 | |
| 
 | |
| def find_keyfile_extension(node, key_name):
 | |
|     formatted_key_name = format_variables(node, key_name)
 | |
| 
 | |
|     for extension in ('asc', 'gpg'):
 | |
|         if exists(join(node.repo.path, 'data', 'apt', 'keys', f'{formatted_key_name}.{extension}')):
 | |
|             return extension
 | |
|     else:
 | |
|         raise Exception(f"no keyfile '{formatted_key_name}.(asc|gpg)' found")
 | |
| 
 | |
| 
 | |
| # https://manpages.ubuntu.com/manpages/latest/en/man5/apt.conf.5.html
 | |
| def render_apt_conf(section, depth=0):
 | |
|     buffer = ''
 | |
| 
 | |
|     for k,v in sorted(section.items()):
 | |
|         if isinstance(v, dict):
 | |
|             # element is a sub section
 | |
|             assert match(r'^[a-zA-Z/\-\:\.\_\+]*$', k) and not match(r'::', k)
 | |
|             buffer += ' '*4*depth + k + ' {\n'
 | |
|             buffer += render_apt_conf(v, depth=depth+1)
 | |
|             buffer += ' '*4*depth + '}\n'
 | |
|         elif isinstance(v, (set, list)):
 | |
|             # element is a value list
 | |
|             buffer += ' '*4*depth + k + ' {\n'
 | |
|             for e in sorted(v):
 | |
|                 buffer += ' '*4*(depth+1) + '"' + e + '";\n'
 | |
|             buffer += ' '*4*depth + '}\n'
 | |
|         else:
 | |
|             # element is a single value
 | |
|             buffer += ' '*4*depth + k + ' "' + v + '";\n'
 | |
| 
 | |
|     return buffer
 | |
| 
 | |
| 
 | |
| 
 | |
| # https://manpages.debian.org/latest/apt/sources.list.5.de.html
 | |
| # https://repolib.readthedocs.io/en/latest/deb822-format.html
 | |
| def render_source(node, source_name):
 | |
|     config = node.metadata.get(f'apt/sources/{source_name}')
 | |
|     lines = []
 | |
| 
 | |
|     keys_and_types = {
 | |
|         'types': (set, list),
 | |
|         'urls': (set, list),
 | |
|         'suites': (set, list),
 | |
|         'components': (set, list),
 | |
|         'options': dict,
 | |
|         'key': str,
 | |
|     }
 | |
| 
 | |
|     for key, value in config.items():
 | |
|         if key not in keys_and_types:
 | |
|             raise Exception(f"{node}: invalid source '{source_name}' conf key: '{key}' (expecting one of: {', '.join(keys_and_types)})")
 | |
|         elif not isinstance(value, keys_and_types[key]):
 | |
|             raise Exception(f"{node}: invalid source '{source_name}' conf value type for '{key}': '{type(value)}' (expecting: '{keys_and_types[key]}')")
 | |
| 
 | |
|     # X-Repolib-Name
 | |
|     lines.append(
 | |
|         f'X-Repolib-Name: ' + source_name
 | |
|     )
 | |
| 
 | |
|     # types
 | |
|     lines.append(
 | |
|         f'Types: ' + ' '.join(sorted(config.get('types', {'deb'})))
 | |
|     )
 | |
| 
 | |
|     # url
 | |
|     lines.append(
 | |
|         f'URIs: ' + ' '.join(sorted(config['urls']))
 | |
|     )
 | |
| 
 | |
|     # suites
 | |
|     lines.append(
 | |
|         f'Suites: ' + ' '.join(sorted(config['suites']))
 | |
|     )
 | |
| 
 | |
|     # components
 | |
|     if 'components' in config:
 | |
|         lines.append(
 | |
|             f'Components: ' + ' '.join(sorted(config['components']))
 | |
|         )
 | |
| 
 | |
|     # options
 | |
|     for key, value in sorted(config['options'].items()):
 | |
|         if isinstance(value, (set, list)):
 | |
|             value = ' '.join(value)
 | |
| 
 | |
|         lines.append(
 | |
|             f'{key}: ' + value
 | |
|         )
 | |
| 
 | |
|     # render to string and format variables
 | |
|     return format_variables(node, '\n'.join(lines) + '\n')
 |