Skip to content

Commit

Permalink
T6674: Add build-scrips for packages without Jenkins
Browse files Browse the repository at this point in the history
Add build scripts for .deb packages without Jenkins.
To exclude Jenkins we need some place where we can put new builds-scripts
to run in parallel (old/new) during meantime
We will deprecate old Jenkins package builds in the future.
  • Loading branch information
sever-sever committed Aug 28, 2024
1 parent 70bb3c5 commit bb4c831
Show file tree
Hide file tree
Showing 121 changed files with 19,132 additions and 0 deletions.
8 changes: 8 additions & 0 deletions scripts/package-build/aws-gwlbtun/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
aws-gwlbtun*/
*.tar.gz
*.tar.xz
*.deb
*.dsc
*.buildinfo
*.build
*.changes
98 changes: 98 additions & 0 deletions scripts/package-build/aws-gwlbtun/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 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/>.
#

import toml
import os
from argparse import ArgumentParser
from pathlib import Path
from subprocess import run, CalledProcessError
import datetime
import shutil


def prepare_package(repo_dir: str) -> None:
"""Prepare a package"""
install_file = Path(repo_dir) / 'debian/install'
install_data = 'obj-*-linux-gnu/gwlbtun usr/sbin'
install_file.parent.mkdir(parents=True, exist_ok=True)
install_file.touch()
install_file.write_text(install_data)


def build_package(package: dict) -> None:
"""Build a package from the repository
Args:
package (dict): Package information
"""
timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
versioned_name = f"{package['name']}-{timestamp}-{package['commit_id']}"
repo_dir = Path(versioned_name)

try:
# Clone the repository
run(f"git clone {package['scm_url']} {repo_dir}", check=True, shell=True)

# Check out the specific commit
run(
f"git checkout {package['commit_id']}", cwd=repo_dir, check=True, shell=True
)

# Prepare and build the package
debmake_cmd = [
'debmake',
'-e',
'support@vyos.io',
'-f',
'VyOS Support',
'-p',
package['name'],
'-u',
f"{timestamp}-{package['commit_id']}",
'-t',
]
run(debmake_cmd, cwd=repo_dir, check=True)

prepare_package(repo_dir)

run('debuild', cwd=repo_dir, check=True, shell=True)

except CalledProcessError as e:
print(f"Failed to build package {package['name']}: {e}")
finally:
# Clean up
pass
# shutil.rmtree(repo_dir, ignore_errors=True)


if __name__ == '__main__':
# Prepare argument parser
arg_parser = ArgumentParser()
arg_parser.add_argument(
'--config',
default='package.toml',
help='Path to the package configuration file',
)
args = arg_parser.parse_args()

# Load package configuration
with open(args.config, 'r') as file:
config = toml.load(file)

package = config['package']

build_package(package)
4 changes: 4 additions & 0 deletions scripts/package-build/aws-gwlbtun/package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "aws-gwlbtun"
commit_id = "f78058a"
scm_url = "https://github.com/aws-samples/aws-gateway-load-balancer-tunnel-handler"
184 changes: 184 additions & 0 deletions scripts/package-build/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 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/>.
#

import glob
import shutil
import toml
import os

from argparse import ArgumentParser
from pathlib import Path
from subprocess import run, CalledProcessError


def ensure_dependencies(dependencies: list) -> None:
"""Ensure Debian build dependencies are met"""
if not dependencies:
print("I: No additional dependencies to install")
return

print("I: Ensure Debian build dependencies are met")
run(['sudo', 'apt-get', 'update'], check=True)
run(['sudo', 'apt-get', 'install', '-y'] + dependencies, check=True)


def apply_patches(repo_dir: Path, patch_dir: Path) -> None:
"""Apply patches from the patch directory to the repository"""
if not patch_dir.exists() or not patch_dir.is_dir():
print(f"I: Patch directory {patch_dir} does not exist, skipping patch application")
return

patches = sorted(patch_dir.glob('*'))
if not patches:
print(f"I: No patches found in {patch_dir}")
return

debian_patches_dir = repo_dir / 'debian/patches'
debian_patches_dir.mkdir(parents=True, exist_ok=True)

series_file = debian_patches_dir / 'series'
with series_file.open('a') as series:
for patch in patches:
patch_dest = debian_patches_dir / patch.name
shutil.copy(patch, patch_dest)
series.write(patch.name + '\n')
print(f"I: Applied patch: {patch.name}")


def prepare_package(repo_dir: Path, install_data: str) -> None:
"""Prepare a package"""
if not install_data:
print("I: No install data provided, skipping package preparation")
return

try:
install_file = repo_dir / 'debian/install'
install_file.parent.mkdir(parents=True, exist_ok=True)
install_file.write_text(install_data)
print("I: Prepared package")
except Exception as e:
print(f"Failed to prepare package: {e}")
raise


def build_package(package: list, dependencies: list, patch_dir: Path) -> None:
"""Build a package from the repository
Args:
package (list): List of Packages from toml
dependencies (list): List of additional dependencies
patch_dir (Path): Directory containing patches
"""
repo_name = package['name']
repo_dir = Path(repo_name)

try:
# Clone the repository if it does not exist
if not repo_dir.exists():
run(['git', 'clone', package['scm_url'], str(repo_dir)], check=True)

# Check out the specific commit
run(['git', 'checkout', package['commit_id']], cwd=repo_dir, check=True)

# Ensure dependencies
ensure_dependencies(dependencies)

# Apply patches if any
if (repo_dir / 'patches'):
apply_patches(repo_dir, patch_dir)

# Prepare the package if required
if package.get('prepare_package', False):
prepare_package(repo_dir, package.get('install_data', ''))

# Build dependency package and install it
if (repo_dir / 'debian/control').exists():
try:
run('sudo mk-build-deps --install --tool "apt-get --yes --no-install-recommends"', cwd=repo_dir, check=True, shell=True)
run('sudo dpkg -i *build-deps*.deb', cwd=repo_dir, check=True, shell=True)
except CalledProcessError as e:
print(f"Failed to build package {repo_name}: {e}")

# Build the package, check if we have build_cmd in the package.toml
try:
build_cmd = package.get('build_cmd', 'dpkg-buildpackage -uc -us -tc -F')
run(build_cmd, cwd=repo_dir, check=True, shell=True)
except CalledProcessError as e:
print(e)
print("I: Source packages build failed, ignoring - building binaries only")
build_cmd = package.get('build_cmd', 'dpkg-buildpackage -uc -us -tc -b')
run(build_cmd, cwd=repo_dir, check=True, shell=True)

except CalledProcessError as e:
print(f"Failed to build package {repo_name}: {e}")
finally:
# Clean up repository directory
# shutil.rmtree(repo_dir, ignore_errors=True)
pass


def cleanup_build_deps(repo_dir: Path) -> None:
"""Clean up build dependency packages"""
try:
if repo_dir.exists():
for file in glob.glob(str(repo_dir / '*build-deps*.deb')):
os.remove(file)
print("I: Cleaned up build dependency packages")
except Exception as e:
print(f"Error cleaning up build dependencies: {e}")


def copy_packages(repo_dir: Path) -> None:
"""Copy generated .deb packages to the parent directory"""
try:
deb_files = glob.glob(str(repo_dir / '*.deb'))
for deb_file in deb_files:
shutil.copy(deb_file, repo_dir.parent)
print(f'I: copy generated "{deb_file}" package')
except Exception as e:
print(f"Error copying packages: {e}")


if __name__ == '__main__':
# Prepare argument parser
arg_parser = ArgumentParser()
arg_parser.add_argument('--config',
default='package.toml',
help='Path to the package configuration file')
arg_parser.add_argument('--patch-dir',
default='patches',
help='Path to the directory containing patches')
args = arg_parser.parse_args()

# Load package configuration
with open(args.config, 'r') as file:
config = toml.load(file)

packages = config['packages']
patch_dir = Path(args.patch_dir)

for package in packages:
dependencies = package.get('dependencies', {}).get('packages', [])

# Build the package
build_package(package, dependencies, patch_dir)

# Clean up build dependency packages after build
cleanup_build_deps(Path(package['name']))

# Copy generated .deb packages to parent directory
copy_packages(Path(package['name']))
7 changes: 7 additions & 0 deletions scripts/package-build/ddclient/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ddclient/
*.buildinfo
*.build
*.changes
*.deb
*.dsc

1 change: 1 addition & 0 deletions scripts/package-build/ddclient/build.py
4 changes: 4 additions & 0 deletions scripts/package-build/ddclient/package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[[packages]]
name = "ddclient"
commit_id = "debian/3.11.2-1"
scm_url = "https://salsa.debian.org/debian/ddclient"
7 changes: 7 additions & 0 deletions scripts/package-build/dropbear/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dropbear/
*.buildinfo
*.build
*.changes
*.deb
*.dsc

1 change: 1 addition & 0 deletions scripts/package-build/dropbear/build.py
7 changes: 7 additions & 0 deletions scripts/package-build/dropbear/package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[[packages]]
name = "dropbear"
commit_id = "debian/2022.83-1+deb12u1"
scm_url = "https://salsa.debian.org/debian/dropbear.git"

[packages.dependencies]
packages = ["libpam0g-dev"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
From 861bfb53de5909e25a952a83654c63de61af02b5 Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Sun, 28 May 2023 15:45:32 +0200
Subject: [PATCH] Enable PAM support

---
debian/control | 1 +
debian/rules | 2 +-
default_options.h | 4 ++--
3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/debian/control b/debian/control
index 77ea036..b252b97 100644
--- a/debian/control
+++ b/debian/control
@@ -6,6 +6,7 @@ Build-Depends: debhelper,
debhelper-compat (= 13),
libtomcrypt-dev (>= 1.18.2~),
libtommath-dev (>= 1.2.0~),
+ libpam0g-dev,
libz-dev
Rules-Requires-Root: no
Standards-Version: 4.6.1
diff --git a/debian/rules b/debian/rules
index 7dab64c..ce11aa4 100755
--- a/debian/rules
+++ b/debian/rules
@@ -24,7 +24,7 @@ endif
dh $@

override_dh_auto_configure:
- dh_auto_configure -- --disable-bundled-libtom \
+ dh_auto_configure -- --disable-bundled-libtom --enable-pam \
CC='$(CC)' CFLAGS='$(CFLAGS)' $(CONFFLAGS)

execute_before_dh_auto_build:
diff --git a/default_options.h b/default_options.h
index 5132775..e7d274c 100644
--- a/default_options.h
+++ b/default_options.h
@@ -223,7 +223,7 @@ group1 in Dropbear server too */

/* Authentication Types - at least one required.
RFC Draft requires pubkey auth, and recommends password */
-#define DROPBEAR_SVR_PASSWORD_AUTH 1
+#define DROPBEAR_SVR_PASSWORD_AUTH 0

/* Note: PAM auth is quite simple and only works for PAM modules which just do
* a simple "Login: " "Password: " (you can edit the strings in svr-authpam.c).
@@ -231,7 +231,7 @@ group1 in Dropbear server too */
* but there's an interface via a PAM module. It won't work for more complex
* PAM challenge/response.
* You can't enable both PASSWORD and PAM. */
-#define DROPBEAR_SVR_PAM_AUTH 0
+#define DROPBEAR_SVR_PAM_AUTH 1

/* ~/.ssh/authorized_keys authentication.
* You must define DROPBEAR_SVR_PUBKEY_AUTH in order to use plugins. */
--
2.30.2

Loading

0 comments on commit bb4c831

Please sign in to comment.