def main(): 'build and install a vyos debian package' arg = arguments.setup(__doc__, ['build']) control = Control(arg.dry, not arg.quiet) if not config.exists(arg.server): sys.exit(f'machine "{arg.server}" is not configured\n') if not config.exists(arg.router): sys.exit(f'machine "{arg.router}" is not configured\n') role = config.get(arg.server, 'role') if role != 'build': sys.exit(f'target "{arg.server}" is not a build machine\n') role = config.get(arg.router, 'role') if role != 'router': sys.exit(f'target "{arg.router}" is not a VyOS router\n') control.git(arg.server, f'checkout current') control.git(arg.server, f'pull') control.cleanup(arg.server) for package in arg.packages: control.build(arg.server, package, 'current', arg.working) control.install(arg.server, arg.router, package, arg.working) log.completed('package(s) installed')
def setup_branch(self, branch, repo): cloning = os.path.join(config.get('global', 'cloning_dir'), repo) folder = os.path.join(config.get('global', 'working_dir'), branch) working = os.path.join(folder, repo) if not os.path.exists(working): self.make(folder) self.into(folder) self.run(f'cp -a {cloning} {repo}') self.into(working) self.run(f'git checkout -b {branch}')
def makeup(target): if target.startswith('http'): image = target.split('/')[-1] location = os.path.join(config.get('global', 'store'), image) elif target.startswith('/'): image = target.split('/')[-1] location = target else: image = latest(target) location = os.path.join(config.get('global', 'store'), image) url = f'https://downloads.vyos.io/rolling/current/amd64/{image}' return image, location, url
def permission(self, where, folder): user = config.get(where, 'user') with Repository(folder, verbose=self.verbose): for src, dst in self.move: self.ssh(where, f'sudo chown -R {user} {dst}') self.ssh(where, f'sudo chgrp -R vyattacfg {dst}') self.ssh(where, f'sudo chmod -R g+rxw {dst}')
def fetch(self, where): build_repo = config.get(where, 'repo') when = datetime.now().strftime('%Y%M%d%H%M') iso = f'vyos-1.3-rolling-{when}-amd64.iso' self.chain( config.ssh(where, f'cat {build_repo}/build/live-image-amd64.hybrid.iso'), f'cat - > {iso}' )
def setup_source(self, repo): cloning = config.get('global', 'cloning_dir') working = os.path.join(cloning, repo) user = config.get('global', 'github') if not os.path.exists(working): self.make(cloning) self.into(cloning) self.run(f'git clone [email protected]:{user}/{repo}') self.into(working) self.run(f'git remote add upstream git://github.com/vyos/{repo}') branch = 'current' if repo in ('vyos-smoketest', ): branch = 'master' self.make(working) self.into(working) self.run(f'git checkout {branch}') self.run(f'git reset --hard HEAD') self.run(f'git pull upstream --tags {branch}') self.run(f'git push origin {branch}')
def install(self, server, router, vyos_repo, location): build_repo = config.get(server, 'repo') with Repository(os.path.join(location, vyos_repo), verbose=self.verbose) as debian: package = debian.package(vyos_repo) if not package: log.failed(f'could not find {vyos_repo} package name') if not self.dry: log.note(f'installing {package}') self.chain(config.ssh(server, f'cat {build_repo}/{self.location}/{package}'), config.ssh(router, f'cat - > {package}')) self.ssh(router, f'sudo dpkg -i --force-all {package}') self.ssh(router, f'rm {package}')
def backdoor(self, where, password): build_repo = config.get(where, 'repo') lines = config.read('vyos-iso-backdoor').split('\n') location = lines.pop(0).lstrip().lstrip('#').strip() if not password: self.ssh(where, f"rm {build_repo}/{location}/vyos*", exitonfail=False) self.ssh(where, f"rm {build_repo}/{location}/vyatta*", exitonfail=False) return data = ''.join(lines).format(user='******', password=password) self.chain(config.printf(data), config.ssh(where, f'cat - > {build_repo}/{location}'))
def main(target=''): 'call vyos-build make within docker' options = ['make'] if not target: options = ['target'] + options arg = arguments.setup(__doc__, options) if not target: target = arg.target release = arg.release or 'current' control = Control(arg.dry, not arg.quiet) if not config.exists(arg.server): sys.exit(f'machine "{arg.server}" is not configured') role = config.get(arg.server, 'role') if role != 'build': sys.exit(f'target "{arg.server}" is not a build machine') control.cleanup(arg.server) # to re-add the vyos-1x folder we deleted control.git(arg.server, 'checkout packages') control.git(arg.server, f'checkout {release}') control.git(arg.server, 'pull') control.docker_pull(arg.server, release) if target == 'test': control.make(arg.server, release, 'test') return done = False if not arg.release: for package in arg.packages: done = control.build(arg.server, package, 'current', arg.working) if done: control.backdoor(arg.server, arg.backdoor) if done or arg.release: control.configure(arg.server, release, arg.extra, arg.name) control.make(arg.server, release, target) if target == 'iso' and arg.test: control.make(arg.server, release, 'test') if arg.save: control.fetch(arg.server) log.completed('iso built and tested')
def main(): 'update a VyOS router filesystem with newer vyos-1x code' arg = arguments.setup(__doc__, ['update']) control = Control(arg.dry, not arg.quiet) if not config.exists(arg.router): sys.exit(f'machine "{arg.router}" is not configured\n') role = config.get(arg.router, 'role') if role != 'router': sys.exit(f'target "{arg.router}" is not a VyOS router\n') control.permission(arg.router, arg.working) control.rsync(arg.router, arg.working) control.update(arg.router, arg.working)
def build(self, where, vyos_repo, release, folder): build_repo = config.get(where, 'repo') self.ssh(where, f'mkdir -p {build_repo}/{self.location}/{vyos_repo}') with Repository(os.path.join(folder, vyos_repo), verbose=self.verbose) as debian: package = debian.package(vyos_repo) if not package: log.failed(f'could not find {vyos_repo} package version', verbose=self.verbose) elif not self.dry: log.note(f'building package {package}') self.run(config.rsync(where, '.', f'{build_repo}/{self.location}/{vyos_repo}')) self.ssh(where, config.docker(where, release, f'{self.location}/{vyos_repo}', 'dpkg-buildpackage -uc -us -tc -b')) return True
def main(): 'set a machine for this tool' arg = arguments.setup(__doc__, ['setup']) control = Control(arg.dry, not arg.quiet) if not config.exists(arg.machine): sys.exit(f'machine "{arg.machine}" is not configured\n') role = config.get(arg.machine, 'role') if not role: print('the machine "{arg.machine}" is not setup') if role == 'router': control.setup_router(arg.machine) elif role == 'build': control.setup_build(arg.machine, arg.sudo) else: log.completed('the machine "{arg.machine}" is not correctly setup')
def configure(self, where, release, extra, name): email = config.get('global', 'email') date = datetime.now().strftime('%Y%m%d%H%M') if name: version = f'{release}-{name}-{date}' else: version = f'{release}-{date}' configure = f"--build-by {email}" # configure += f" --debian-mirror http://ftp.de.debian.org/debian/" configure += f" --version {version}" configure += f" --build-type release" if extra: configure += f" --custom-package '{extra}'" self.ssh(where, config.docker(where, release, '', f'git checkout {release}')) self.ssh(where, config.docker(where, release, '', f'./configure {configure}'))
def main(): 'upgrade router to latest VyOS image' arg = arguments.setup(__doc__, ['upgrade']) control = Control(arg.dry, not arg.quiet) if not config.exists(arg.router): sys.exit(f'machine "{arg.router}" is not configured\n') role = config.get(arg.router, 'role') if role != 'router': sys.exit(f'target "{arg.router}" is not a VyOS router\n') location = os.path.abspath(arg.iso) if arg.iso else fetch(arg.iso) time.sleep(0.5) control.upgrade(arg.router, arg.bind, location, arg.local, arg.remote, arg.dry) if arg.reboot: control.reboot(arg.router)
def docker(self, where): build_repo = config.get(where, 'repo') when = datetime.now().strftime('%Y%M%d%H%M') vyos_iso = f'{build_repo}/build/live-image-amd64.hybrid.iso' root_iso = f'{build_repo}/build/iso' root_oci = f'{build_repo}/build/oci' self.ssh(where, f'sudo rm -rf {root_iso} {root_oci}', exitonfail=False) self.ssh(where, f'sudo umount {root_iso}/', exitonfail=False) self.ssh(where, f'sudo mkdir -p {root_iso} {root_oci}') self.ssh(where, f'sudo mount -t iso9660 -o loop {vyos_iso} {root_iso}/') self.ssh(where, f'sudo unsquashfs -f -d {root_oci}/ {root_iso}/live/filesystem.squashfs') self.ssh(where, f"sudo sed -i 's/^LANG=.*$/LANG=C.UTF-8/' {root_oci}/etc/default/locale") self.ssh(where, f'sudo rm -rf {root_oci}/boot/*.img') self.ssh(where, f'sudo rm -rf {root_oci}/boot/*vyos*') self.ssh(where, f'sudo rm -rf {root_oci}/boot/vmlinuz') self.ssh(where, f'sudo rm -rf {root_oci}/vmlinuz') self.ssh(where, f'sudo rm -rf {root_oci}/usr/lib/x86_64-linux-gnu/libwireshark.so.*') self.ssh(where, f'sudo tar -C {root_oci} -c . | docker import - vyos:{when}') self.ssh(where, f'sudo umount {root_iso}/') self.ssh(where, f'sudo rm -rf {root_iso} {root_oci}')
def setup_build(self, where, with_sudo): packages = 'qemu-kvm libvirt-clients libvirt-daemon-system' packages += ' git rsync docker.io docker-compose' # for crux packages += ' apt-transport-https ca-certificates curl' packages += ' gnupg2 software-properties-common' # for docker image packages += ' squashfs-tools' repo = config.get(where, 'repo') repo_name = os.path.basename(repo) repo_folder = os.path.dirname(repo) _, _, code = self.ssh(where, f"test -d {repo}", exitonfail=False) if code == 0: print('this machine is already setup') return username = config.get(where, 'user') password = '******' if with_sudo: if not self.dry: print('----') print("Please enter the host root password (it is not saved)") print("It is required to setup password-less command via sudo") password = getpass('password: '******'{password}'" print('----') print('setting up sudo ...') print('----') if self._sudo(where, password, 'apt-get install --yes sudo', exitonfail=False): self._sudo(where, password, 'adduser ${USER} sudo') if self._sudo(where, password, 'grep NOPASSWD /etc/sudoers', exitonfail=False): sed = f"sed -i '$ a\{username} ALL=(ALL) NOPASSWD: ALL' /etc/sudoers" # noqa: W605,E501 self._sudo(where, password, sed) else: print('sudo is already setup') print('----') print( 'updating the OS to make sure the packages are on the latest version' ) print('it may take some time ...') print('----') self.ssh(where, password, 'sudo dpkg --configure -a') self.ssh(where, password, 'sudo apt-get --yes upgrade') self.ssh(where, password, 'sudo apt-get update', exitonfail=False) print('----') print('installing packages required for building VyOS') print('----') print('----') print('adding keys for debian') print('----') # crux self.ssh( where, 'curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -' ) # crux # self.ssh(where, 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7EA0A9C3F273FCD8') # self._sudo(where, 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9D6D8F6BC857C906') # self._sudo(where, 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0E08A149DE57BFBE') # self._sudo(where, 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010') # self._sudo(where, 'sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 32C249BD0DF04B5C') # crux self.ssh( where, 'sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"' ) self.ssh( where, f'sudo apt-get --yes --no-install-recommends install {packages}' ) # noqa: E501 print('----') print('adding the right permission to the user') print('----') self.ssh(where, f'sudo adduser {username} libvirt') # no f-string here in purpose we want ${USER} self.ssh(where, 'sudo usermod -aG docker ${USER}') print('----') print('installing VyOS docker build image') print('----') self.ssh(where, 'sudo systemctl restart docker.service') self.docker_pull(where, 'crux') self.docker_pull(where, 'current') print('----') print('installing vyos-build') print('----') self.ssh(where, f'mkdir -p {repo_folder}') self.ssh(where, f'rm -rf {repo_folder}/{repo_name}', exitonfail=False) self.ssh( where, f"cd {repo_folder} && " f"test '!' -d vyos-built && " f"git clone https://github.com/vyos/vyos-build.git {repo_name}", exitonfail=False, ) self.ssh(where, f'cd {repo} && git pull') # self.ssh(where, 'cd ~/vyos/vyos-build && docker build -t vyos-builder docker') print('----') print("Please logout and log back in if you have installed locally")
def branched_repo(self, branch, repo): return os.path.join(config.get('global', 'working_dir'), branch, repo)
def edit(self, folder): editor = config.get('global', 'editor') self.run(f'{editor} {folder}')
def git(self, where, action): build_repo = config.get(where, 'repo') self.ssh(where, f'cd {build_repo} && git {action}', 'Already up')
def cleanup(self, where): build_repo = config.get(where, 'repo') self.ssh(where, f"rm -rf {build_repo}/{self.location}/*", exitonfail=False)