mirror of
				https://github.com/vyos/vyos-build.git
				synced 2025-10-01 20:28:40 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| #
 | |
| # Copyright (C) 2019, VyOS maintainers and contributors
 | |
| #
 | |
| # This program is free software; you can redistribute it and/or modify
 | |
| # it under the terms of the GNU General Public License version 2 or later as
 | |
| # published by the Free Software Foundation.
 | |
| #
 | |
| # This program is distributed in the hope that it will be useful,
 | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| # GNU General Public License for more details.
 | |
| #
 | |
| # You should have received a copy of the GNU General Public License
 | |
| # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| #
 | |
| # File: build-config
 | |
| # Purpose:
 | |
| #  This script serves the same purpose as ./configure in traditional
 | |
| #   autoconf setups.
 | |
| #  It takes build configuration options from command line, checks them,
 | |
| #  builds a config dictionary, augments it with some default and/or
 | |
| #  computed values and saves it to build/build-config.json
 | |
| #  for other build scripts to read.
 | |
| 
 | |
| import argparse
 | |
| import re
 | |
| import sys
 | |
| import os
 | |
| import getpass
 | |
| import platform
 | |
| import json
 | |
| 
 | |
| import defaults
 | |
| 
 | |
| # argparse converts hyphens to underscores,
 | |
| # so for lookups in the original options hash we have to
 | |
| # convert them back
 | |
| def field_to_option(s):
 | |
|     return re.sub(r'_', '-', s)
 | |
| 
 | |
| def get_default_build_by():
 | |
|     return "{user}@{host}".format(user= getpass.getuser(), host=platform.node())
 | |
| 
 | |
| def get_validator(optdict, name):
 | |
|     try:
 | |
|         return optdict[name][2]
 | |
|     except KeyError:
 | |
|         return None
 | |
| 
 | |
| def load_config(filename):
 | |
|     with open(filename, 'r') as f:
 | |
|         print(f'Loading {filename}')
 | |
|         this_config = json.load(f)
 | |
| 
 | |
|     if not 'inherit_from' in this_config:
 | |
|       print(f'No inheritance detected')
 | |
|       return this_config
 | |
| 
 | |
|     inherited_config = load_config(this_config['inherit_from'])
 | |
|     del this_config['inherit_from']
 | |
|     inherited_config.update(this_config)
 | |
|     return inherited_config
 | |
| 
 | |
| 
 | |
| # Load the build flavor file
 | |
| build_flavor = os.getenv('VYOS_BUILD_FLAVOR')
 | |
| if build_flavor is None:
 | |
|     build_flavor = defaults.DEFAULT_BUILD_FLAVOR
 | |
| try:
 | |
|     build_defaults = load_config(build_flavor)
 | |
| except Exception as e:
 | |
|     print("Failed to open the build flavor file {0}: {1}".format(build_flavor, e))
 | |
|     sys.exit(1)
 | |
| 
 | |
| 
 | |
| # Options dict format:
 | |
| # '$option_name_without_leading_dashes': { ('$help_string', $default_value_generator_thunk, $value_checker_thunk) }
 | |
| options = {
 | |
|    'architecture': ('Image target architecture (amd64 or i386 or armhf or arm64)', lambda: build_defaults['architecture'], lambda x: x in ['amd64', 'i386', 'armhf', 'arm64']),
 | |
|    'build-by': ('Builder identifier (e.g. jrandomhacker@example.net)', get_default_build_by, None),
 | |
|    'debian-mirror': ('Debian repository mirror for ISO build', lambda: build_defaults['debian_mirror'], None),
 | |
|    'debian-security-mirror': ('Debian security updates mirror', lambda: build_defaults['debian_security_mirror'], None),
 | |
|    'pbuilder-debian-mirror': ('Debian repository mirror for pbuilder env bootstrap', lambda: build_defaults['debian_mirror'], None),
 | |
|    'vyos-mirror': ('VyOS package mirror', lambda: build_defaults["vyos_mirror"], None),
 | |
|    'build-type': ('Build type, release or development', lambda: 'development', lambda x: x in ['release', 'development']),
 | |
|    'version': ('Version number (release builds only)', None, None),
 | |
|    'build-comment': ('Optional build comment', lambda: '', None)
 | |
| }
 | |
| 
 | |
| # Create the option parser
 | |
| parser = argparse.ArgumentParser()
 | |
| for k, v in options.items():
 | |
|     help_string, default_value_thunk = v[0], v[1]
 | |
|     if default_value_thunk is None:
 | |
|         parser.add_argument('--' + k, type=str, help=help_string)
 | |
|     else:
 | |
|         parser.add_argument('--' + k, type=str, help=help_string, default=default_value_thunk())
 | |
| 
 | |
| # The debug option is a bit special since it's different type
 | |
| parser.add_argument('--debug', help="Enable debug output", action='store_true')
 | |
| 
 | |
| # Custom APT entry and APT key options can be used multiple times
 | |
| parser.add_argument('--custom-apt-entry', help="Custom APT entry", action='append')
 | |
| parser.add_argument('--custom-apt-key', help="Custom APT key file", action='append')
 | |
| parser.add_argument('--custom-package', help="Custom package to install from repositories", action='append')
 | |
| 
 | |
| args = vars(parser.parse_args())
 | |
| 
 | |
| # Validate options
 | |
| for k, v in args.items():
 | |
|     key = field_to_option(k)
 | |
|     func = get_validator(options, k)
 | |
|     if func is not None:
 | |
|         if not func(v):
 | |
|             print("{v} is not a valid value for --{o} option".format(o=key, v=v))
 | |
|             sys.exit(1)
 | |
| 
 | |
| # Some fixup for mirror settings.
 | |
| # The idea is: if --debian-mirror is specified but --pbuilder-debian-mirror is not,
 | |
| # use the --debian-mirror value for both lb and pbuilder bootstrap
 | |
| if (args['debian_mirror'] != build_defaults["debian_mirror"]) and \
 | |
|    (args['pbuilder_debian_mirror'] == build_defaults["debian_mirror"]):
 | |
|     args['pbuilder_debian_mirror'] = args['debian_mirror']
 | |
| 
 | |
| # Version can only be set for release builds,
 | |
| # for dev builds it hardly makes any sense
 | |
| if args['build_type'] == 'development':
 | |
|     if args['version'] is not None:
 | |
|         print("Version can only be set for release builds")
 | |
|         print("Use --build-type=release option if you want to set version number")
 | |
|         sys.exit(1)
 | |
| 
 | |
| # Populate some defaults that are not configurable,
 | |
| # but that are handy to have in the options hash
 | |
| args['distribution'] = build_defaults["debian_distribution"]
 | |
| args['build_dir'] = defaults.BUILD_DIR
 | |
| args['pbuilder_config'] = defaults.PBUILDER_CONFIG
 | |
| args['vyos_branch'] = build_defaults["vyos_branch"]
 | |
| args['release_train'] = build_defaults["release_train"]
 | |
| 
 | |
| # Add custom packages from build defaults
 | |
| if not args['custom_package']:
 | |
|     args['custom_package'] = []
 | |
| args['custom_package'] = args['custom_package'] + build_defaults['custom_packages']
 | |
| 
 | |
| if not args['custom_apt_entry']:
 | |
|     args['custom_apt_entry'] = []
 | |
| args['custom_apt_entry'] = args['custom_apt_entry'] + build_defaults['additional_repositories']
 | |
| 
 | |
| 
 | |
| # Check the build environment and dependencies
 | |
| env_check_retval = os.system("scripts/check-build-env")
 | |
| if env_check_retval > 0:
 | |
|     print("Build environment check failed, fix the issues and retry")
 | |
| 
 | |
| args['kernel_version'] = build_defaults['kernel_version']
 | |
| args['kernel_flavor'] = build_defaults['kernel_flavor']
 | |
| args['bootloaders'] = build_defaults['bootloaders']
 | |
| 
 | |
| 
 | |
| # Save to file
 | |
| os.makedirs(defaults.BUILD_DIR, exist_ok=True)
 | |
| print("Saving the build config to {0}".format(defaults.BUILD_CONFIG))
 | |
| with open(defaults.BUILD_CONFIG, 'w') as f:
 | |
|     json.dump(args, f, indent=4, sort_keys=True)
 | |
|     print("\n", file=f)
 | |
| 
 |