diff options
| author | dd <dd@wx.tnyzeq.icu> | 2024-10-07 13:59:41 +0200 |
|---|---|---|
| committer | dd <dd@wx.tnyzeq.icu> | 2024-10-07 13:59:41 +0200 |
| commit | 0fffb7863ee701e52ff6a5cc1db9fe25bf566a99 (patch) | |
| tree | 503e49480b3ddd17b031cb534f4223d4b28e5cc9 | |
| parent | 7bc109ed9a701123bea0fbfecdd9fe09f2a525bc (diff) | |
| download | vyos-jenkins-0fffb7863ee701e52ff6a5cc1db9fe25bf566a99.tar.gz vyos-jenkins-0fffb7863ee701e52ff6a5cc1db9fe25bf566a99.zip | |
ported debranding to new build method for circinus
| -rwxr-xr-x | new/image_builder.py | 21 | ||||
| -rwxr-xr-x | new/install-dependencies.sh | 2 | ||||
| -rw-r--r-- | new/lib/debranding.py | 188 | ||||
| -rw-r--r-- | new/lib/git.py | 1 | ||||
| -rwxr-xr-x | new/package_builder.py | 34 | ||||
| -rw-r--r-- | new/resources/not-vyos/splash.png | bin | 0 -> 4291 bytes |
6 files changed, 237 insertions, 9 deletions
diff --git a/new/image_builder.py b/new/image_builder.py index 817353a..cb5f879 100755 --- a/new/image_builder.py +++ b/new/image_builder.py @@ -11,7 +11,9 @@ from threading import Thread from time import monotonic import netifaces +import pendulum +from lib.debranding import Debranding from lib.docker import Docker from lib.git import Git from lib.helpers import setup_logging, refuse_root, project_dir, get_my_log_file @@ -25,8 +27,8 @@ class ImageBuilder: vyos_build_repo = None docker = None - def __init__(self, branch, vyos_build_git, vyos_build_docker, vyos_mirror, extra_options, - flavor, build_by, version, bind_addr, bind_port, keep_build): + def __init__(self, branch, vyos_build_git, vyos_build_docker, vyos_mirror, extra_options, flavor, build_by, + version, bind_addr, bind_port, keep_build, debranding: Debranding): self.branch = branch self.vyos_build_git = vyos_build_git self.vyos_build_docker = vyos_build_docker @@ -38,6 +40,7 @@ class ImageBuilder: self.bind_addr = bind_addr self.bind_port = bind_port self.keep_build = keep_build + self.debranding = debranding self.cwd = os.getcwd() @@ -65,6 +68,8 @@ class ImageBuilder: if not git.exists(): git.clone(self.vyos_build_git, self.branch) + self.debranding.remove_image_branding(self.vyos_build_repo) + # TODO: remove me, temporary hack until vyos-build is fixed with open(os.path.join(git.repo_path, "data/build-flavors/generic.toml"), "r+") as file: contents = file.read() @@ -78,7 +83,7 @@ class ImageBuilder: if self.branch in self.version_mapping: version = self.version_mapping[self.branch] else: - version = self.branch + version = "%s-%s" % (self.branch, pendulum.now().format("YYYY-MM-DD")) # build image build_image_pieces = [ @@ -201,6 +206,8 @@ if __name__ == "__main__": try: refuse_root() + debranding = Debranding() + parser = argparse.ArgumentParser() parser.add_argument("branch", help="VyOS branch (current, circinus)") parser.add_argument("--vyos-build-git", default="https://github.com/vyos/vyos-build.git", @@ -215,9 +222,15 @@ if __name__ == "__main__": parser.add_argument("--bind-addr", help="Bind local webserver to static address instead of automatic") parser.add_argument("--bind-port", type=int, help="Bind local webserver to static port instead of random") parser.add_argument("--keep-build", action="store_true", help="Keep previous vyos-build repository") + + debranding.populate_cli_parser(parser) + args = parser.parse_args() + values = vars(args) + + debranding.extract_cli_values(values) - builder = ImageBuilder(**vars(args)) + builder = ImageBuilder(debranding=debranding, **values) builder.build() except KeyboardInterrupt: diff --git a/new/install-dependencies.sh b/new/install-dependencies.sh index c3781f4..6dfe839 100755 --- a/new/install-dependencies.sh +++ b/new/install-dependencies.sh @@ -11,7 +11,7 @@ sudo apt-get update -y sudo apt-get install -y git gpg reprepro # python dependencies (python3-yaml is pyyaml) -sudo apt-get install -y python3 python3-yaml python3-requests python3-pendulum python3-netifaces +sudo apt-get install -y python3 python3-yaml python3-requests python3-pendulum python3-netifaces python3-tomlkit # docker if [ ! -f /etc/apt/sources.list.d/docker.list ]; then diff --git a/new/lib/debranding.py b/new/lib/debranding.py new file mode 100644 index 0000000..490886d --- /dev/null +++ b/new/lib/debranding.py @@ -0,0 +1,188 @@ +import argparse +import logging +import os +import re +from shlex import quote +import shutil + +import tomlkit + +from lib.cache import Cache +from lib.helpers import project_dir + + +class Debranding: + DEFAULT = "NOTvyos" + + keep_branding = None + remove_branding = None + alternative_name = None + + def __init__(self): + self.cache = Cache(os.path.join(project_dir, "build", "debranding-cache.json"), dict, {}) + + def populate_cli_parser(self, parser: argparse.ArgumentParser): + parser.add_argument("--keep-branding", action="store_true", help="Keep VyOS branding as opposite to debranding") + parser.add_argument("--remove-branding", action="store_true", help="Remove VyOS branding (default)") + parser.add_argument("--debranding-name", help="The default name is 'NOTvyos'") + + def extract_cli_values(self, values): + self.keep_branding = values["keep_branding"] + del values["keep_branding"] + self.remove_branding = values["remove_branding"] + del values["remove_branding"] + self.alternative_name = values["debranding_name"] + del values["debranding_name"] + self.remember_settings() + + def remove_package_branding(self, root_dir, package_name): + self.log_settings() + if not self.is_debranding_enabled(): + return + alternative_name = self.get_effective_name() + + if package_name == "vyos-1x": + logging.info("Applying debranding for %s..." % package_name) + + # sagitta & circinus + motd_path = os.path.join(root_dir, "data/templates/login/default_motd.j2") + self.replace_patterns_in_file(motd_path, [ + ("VyOS", alternative_name), + ]) + + login_banner_path = os.path.join(root_dir, "src/conf_mode/system_login_banner.py") + self.replace_patterns_in_file(login_banner_path, [ + ("Welcome to VyOS", "Welcome to %s" % alternative_name), + ]) + + router_init_path = os.path.join(root_dir, "src/init/vyos-router") + self.replace_patterns_in_file(router_init_path, [ + ("VyOS Config", "%s Config" % alternative_name), + ("VyOS router", "%s router" % alternative_name), + ]) + + version_path = os.path.join(root_dir, "src/op_mode/version.py") + self.replace_patterns_in_file(version_path, [ + ("VyOS {{version}}", "%s {{version}}" % alternative_name), + ]) + + airbag_path = os.path.join(root_dir, "python/vyos/airbag.py") + self.replace_patterns_in_file(airbag_path, [ + ("VyOS {{version}}", "%s {{version}}" % alternative_name), + ]) + + # equuleus + login_banner_path = os.path.join(root_dir, "src/conf_mode/system-login-banner.py") + self.replace_patterns_in_file(login_banner_path, [ + ("Welcome to VyOS", "Welcome to %s" % alternative_name), + ]) + + version_path = os.path.join(root_dir, "src/op_mode/show_version.py") + self.replace_patterns_in_file(version_path, [ + ("VyOS {{version}}", "%s {{version}}" % alternative_name), + ]) + + elif package_name == "vyatta-cfg": + logging.info("Applying debranding for %s..." % package_name) + + # equuleus + router_init_path = os.path.join(root_dir, "scripts/init/vyos-router") + self.replace_patterns_in_file(router_init_path, [ + ("VyOS Config", "%s Config" % alternative_name), + ("VyOS router", "%s router" % alternative_name), + ]) + + def remove_image_branding(self, root_dir): + self.log_settings() + if not self.is_debranding_enabled(): + return + alternative_name = self.get_effective_name() + + logging.info("Applying debranding...") + + new_splash = os.path.join(project_dir, "resources/not-vyos/splash.png") + target_splash = os.path.join(root_dir, "data/live-build-config/includes.binary/isolinux/splash.png") + shutil.copy2(new_splash, target_splash) + + # sagitta & circinus + defaults_toml_path = os.path.join(root_dir, "data/defaults.toml") + if os.path.exists(defaults_toml_path): + with open(defaults_toml_path, "r") as file: + data = tomlkit.load(file) + + data["website_url"] = "localhost" + data["support_url"] = "There is no official support." + data["bugtracker_url"] = "DO NOT report bugs to VyOS!" + data["project_news_url"] = "This is unofficial %s build." % alternative_name + + with open(defaults_toml_path, "w") as file: + tomlkit.dump(data, file) + + # equuleus + motd_path = os.path.join(root_dir, "data/live-build-config/includes.chroot/usr/share/vyos/default_motd") + self.replace_patterns_in_file(motd_path, [ + ("VyOS", alternative_name), + (re.compile(r"Check out project news at.*"), "This is unofficial %s build."), + (re.compile(r"and feel free to report bugs at.*"), "DO NOT report bugs to VyOS!"), + ]) + + def replace_patterns_in_file(self, path, patterns): + if not os.path.exists(path): + return + + with open(path, "r") as file: + contents = file.read() + + changed = False + for pattern, replacement in patterns: + if isinstance(pattern, re.Pattern): + contents = pattern.sub(replacement, contents) + changed = True + + if changed: + with open(path, "w") as file: + file.write(contents) + + def is_debranding_enabled(self): + if self.remove_branding: + return True + if self.keep_branding: + return False + + if self.cache.get("remove_branding"): + return True + if self.cache.get("keep_branding"): + return False + + return True + + def get_effective_name(self): + if self.alternative_name is not None: + return self.alternative_name + cached_value = self.cache.get("alternative_name") + if cached_value is not None: + return cached_value + return self.DEFAULT + + + def remember_settings(self): + if self.remove_branding: + self.cache.set("remove_branding", True) + self.cache.set("keep_branding", False) + elif self.keep_branding: + self.cache.set("keep_branding", True) + self.cache.set("remove_branding", False) + if self.alternative_name is not None: + self.cache.set("alternative_name", self.alternative_name) + + def log_settings(self): + if not self.is_debranding_enabled(): + option = "option" if self.keep_branding else "cached option" + logging.info("Using %s --keep-branding to keep VyOS branding intact" % option) + else: + name = self.get_effective_name() + if name == self.DEFAULT: + logging.info("Using %s as default debrainding name" % name) + else: + option = "option" if self.alternative_name is not None else "cached option" + logging.info("Using %s --branding-name=%s as debrainding name" % (option, quote(name))) diff --git a/new/lib/git.py b/new/lib/git.py index 119af46..37bb1a9 100644 --- a/new/lib/git.py +++ b/new/lib/git.py @@ -17,6 +17,7 @@ class Git: )) def pull(self): + execute("git -C %s reset --hard" % quote_all(self.repo_path)) execute("git -C %s pull" % quote_all(self.repo_path)) def get_last_commit_hash(self): diff --git a/new/package_builder.py b/new/package_builder.py index be40de7..b48fdbe 100755 --- a/new/package_builder.py +++ b/new/package_builder.py @@ -9,21 +9,22 @@ import pendulum from lib.apt import Apt from lib.cache import Cache +from lib.debranding import Debranding from lib.docker import Docker from lib.git import Git from lib.github import GitHub from lib.helpers import setup_logging, ProcessException, refuse_root, project_dir, get_my_log_file -class Builder: +class PackageBuilder: build_dir = None docker_image = None updated_repos = None apt = None docker = None - def __init__(self, branch, single_package, dirty_build, ignore_missing_binaries, - skip_build, skip_apt, force_build, vyos_build_docker): + def __init__(self, branch, single_package, dirty_build, ignore_missing_binaries, skip_build, skip_apt, + force_build, vyos_build_docker, debranding: Debranding): self.branch = branch self.single_package = single_package self.dirty_build = dirty_build @@ -32,6 +33,7 @@ class Builder: self.skip_apt = skip_apt self.force_build = force_build self.vyos_build_docker = vyos_build_docker + self.debranding = debranding self.github = GitHub() self.cache = Cache(os.path.join(project_dir, "build", "builder-cache-%s.json" % self.branch), dict, {}) @@ -56,12 +58,26 @@ class Builder: self.docker.pull() self.updated_repos = [] + found = 0 + built = 0 for package in packages.values(): + found += 1 if self.single_package is not None and self.single_package != package["package_name"]: continue logging.info("Processing package: %s" % package["package_name"]) self.build_package(package) + built += 1 + + if built == 0: + if self.single_package is not None: + logging.error("Specified --single-package=%s was not found" % self.single_package) + else: + if found == 0: + logging.error("Something's wrong, no packages were found!") + else: + logging.error("Something's wrong, no packages were built but these were found: %s" % packages) + exit(1) elapsed = round(monotonic() - begin, 3) logging.info("Done in %s seconds, see the result in: %s" % (elapsed, self.apt.get_repo_dir())) @@ -111,6 +127,8 @@ class Builder: else: logging.info("Using shared repository %s" % package["git_url"]) + self.debranding.remove_package_branding(repo_path, package["package_name"]) + if package["build_type"] == "build.py": my_directory = os.path.join(self.build_dir, "vyos-build", package["path"]) if not self.skip_build or new: @@ -187,6 +205,8 @@ if __name__ == "__main__": try: refuse_root() + debranding = Debranding() + parser = argparse.ArgumentParser() parser.add_argument("branch", help="VyOS branch (current, circinus)") parser.add_argument("--single-package", help="Build only this package") @@ -198,9 +218,15 @@ if __name__ == "__main__": parser.add_argument("--force-build", action="store_true") parser.add_argument("--vyos-build-docker", default="vyos/vyos-build", help="Default option uses vyos/vyos-build from dockerhub") + + debranding.populate_cli_parser(parser) + args = parser.parse_args() + values = vars(args) + + debranding.extract_cli_values(values) - builder = Builder(**vars(args)) + builder = PackageBuilder(debranding=debranding, **values) builder.build() except KeyboardInterrupt: diff --git a/new/resources/not-vyos/splash.png b/new/resources/not-vyos/splash.png Binary files differnew file mode 100644 index 0000000..5dd0028 --- /dev/null +++ b/new/resources/not-vyos/splash.png |
