#!/bin/sh -ex # Environment variables: # * DISTRO: linux distribution name (e.g. "centos8") # * FEED: binary package feed (e.g. "latest", "nightly") # * KEEP_CACHE: set to 1 to keep downloaded binary packages (for development) # * PROJ: OBS project namespace (e.g. "osmocom:latest") # * PROJ_CONFLICT: Conflicting OBS project namespace (e.g. "osmocom:nightly") # * SKIP_PREPARE_VM: for development, skip the prepare_vm code # * TESTS: which tests to run (see repo-install-test.sh) # Systemd services that must start up successfully after installing all packages (OS#3369) # Disabled services: # * osmo-ctrl2cgi (missing config: /etc/osmocom/ctrl2cgi.ini, OS#4108) # * osmo-remsim-client (exits immediately without USB device) # * osmo-trap2cgi (missing config: /etc/osmocom/%N.ini, OS#4108) # * osmo-trx-* (exits immediately without trx device) # * osmo-upf (not available for debian 10, gets added in services_check()) SERVICES=" osmo-bsc osmo-bts-virtual osmo-cbc osmo-e1d osmo-gbproxy osmo-ggsn osmo-gtphub osmo-hlr osmo-hnbgw osmo-hnodeb osmo-mgw osmo-msc osmo-pcap-client osmo-pcap-server osmo-pcu osmo-remsim-bankd osmo-remsim-server osmo-sgsn osmo-sip-connector osmo-smlc osmo-stp " # Services working in nightly, but not yet in latest SERVICES_NIGHTLY=" osmo-bsc-nat " distro_obsdir() { case "$DISTRO" in centos8) echo "CentOS_8" ;; debian10) echo "Debian_10" ;; debian11) echo "Debian_11" ;; debian12) echo "Debian_12" ;; *) echo "ERROR: unknown obsdir for '$DISTRO'." >&2 exit 1 ;; esac } DISTRO_OBSDIR="$(distro_obsdir)" # $1: OBS project (e.g. "osmocom:nightly" -> "osmocom:/nightly") proj_with_slashes() { echo "$1" | sed "s.:.:/.g" } # $1: OBS project (e.g. "osmocom:nightly" -> "osmocom_nightly") proj_with_underscore() { echo "$1" | tr : _ } check_env() { if [ -n "$FEED" ]; then echo "Checking feed: $FEED" else echo "ERROR: missing environment variable \$FEED!" exit 1 fi if [ -n "$PROJ" ]; then echo "Checking project: $PROJ" else echo "ERROR: missing environment variable \$PROJ!" exit 1 fi if [ -n "$PROJ_CONFLICT" ]; then echo "Checking conflicting project: $PROJ_CONFLICT" else echo "ERROR: missing environment variable \$PROJ_CONFLICT!" exit 1 fi if [ -n "$DISTRO" ]; then echo "Linux distribution: $DISTRO" else echo "ERROR: missing environment variable \$DISTRO!" exit 1 fi if [ -n "$TESTS" ]; then echo "Enabled tests: $TESTS" else echo "ERROR: missing environment variable \$TESTS!" fi } # $1: OBS project (e.g. "osmocom:nightly") configure_osmocom_repo_debian() { local proj="$1" local obs_repo="$DOMAIN/packages/$(proj_with_slashes "$proj")/$DISTRO_OBSDIR/" echo "Configuring Osmocom repository" # Add repository key if ! [ -e /tmp/Release.key ]; then wget -O /tmp/Release.key "https://obs.osmocom.org/projects/$proj/public_key" fi apt-key add /tmp/Release.key echo "deb http://$obs_repo ./" > "/etc/apt/sources.list.d/$proj.list" apt-get update } # $1: OBS project (e.g. "osmocom:nightly") configure_osmocom_repo_debian_remove() { local proj="$1" rm "/etc/apt/sources.list.d/$proj.list" } # $1: OBS project (e.g. "osmocom:nightly") configure_osmocom_repo_centos() { local proj="$1" local baseurl="https://$DOMAIN/packages/$(proj_with_slashes "$proj")/$DISTRO_OBSDIR" echo "Configuring Osmocom repository" # Generate this file, based on the feed: # https://downloads.osmocom.org/packages/osmocom:/latest/CentOS_8/osmocom:latest.repo cat << EOF > "/etc/yum.repos.d/$proj.repo" [$(proj_with_underscore "$proj")] name=$proj type=rpm-md baseurl=$baseurl/ gpgcheck=1 gpgkey=$baseurl/repodata/repomd.xml.key enabled=1 EOF } # $1: OBS project (e.g. "osmocom:nightly") configure_osmocom_repo_centos_remove() { local proj="$1" rm "/etc/yum.repos.d/$proj.repo" } # $1: OBS project (e.g. "osmocom:nightly") configure_osmocom_repo() { case "$DISTRO" in debian*) configure_osmocom_repo_debian "$@" ;; centos*) configure_osmocom_repo_centos "$@" ;; esac } prepare_vm_debian() { # fmtutil fails in tex-common postinst script. This gets installed as # dependency of osmo-gsm-manuals-dev, but is completely unrelated to # what we want to test here so just stub it out. ln -sf /bin/true /usr/bin/fmtutil echo "path-exclude=/usr/bin/fmtutil" >> /etc/dpkg/dpkg.cfg.d/stub apt-get update --allow-releaseinfo-change apt-get install -y --no-install-recommends \ aptitude \ ca-certificates \ gnupg2 \ wget case "$DISTRO" in debian10) # libgnutls30: can't access https://osmocom.org otherwise # ca-certificates-java: fails if installed after java apt-get install -y --no-install-recommends \ ca-certificates-java \ libgnutls30 ;; esac } prepare_vm_centos() { # Install dnf-utils for repoquery dnf install -y dnf-utils # Make additional development libraries available yum config-manager --set-enabled powertools } prepare_vm() { if [ -n "$SKIP_PREPARE_VM" ]; then return fi case "$DISTRO" in debian*) prepare_vm_debian ;; centos*) prepare_vm_centos ;; esac configure_osmocom_repo "$PROJ" } # $1: file # $2-n: patterns to look for in file with grep find_patterns_or_exit() { local file="$1" local pattern shift for pattern in "$@"; do if grep -q "$pattern" "$file"; then continue fi echo "ERROR: could not find pattern '$pattern' in file '$file'!" exit 1 done } test_conflict_debian() { apt-get -y install libosmocore configure_osmocom_repo_debian_remove "$PROJ" configure_osmocom_repo_debian "$PROJ_CONFLICT" (apt-get -y install osmo-mgw 2>&1 && touch /tmp/fail) | tee /tmp/out if [ -e /tmp/fail ]; then echo "ERROR: unexpected exit 0!" exit 1 fi find_patterns_or_exit \ /tmp/out \ "requested an impossible situation" \ "^The following packages have unmet dependencies:" case "$DISTRO" in debian10) find_patterns_or_exit \ /tmp/out \ "Depends: osmocom-" \ "but it is not going to be installed" ;; debian11|debian12) find_patterns_or_exit \ /tmp/out \ "Conflicts: osmocom-" ;; esac configure_osmocom_repo_debian_remove "$PROJ_CONFLICT" configure_osmocom_repo_debian "$PROJ" } test_conflict_centos() { dnf -y install libosmocore-devel configure_osmocom_repo_centos_remove "$PROJ" configure_osmocom_repo_centos "$PROJ_CONFLICT" (dnf -y install osmo-mgw 2>&1 && touch /tmp/fail) | tee /tmp/out if [ -e /tmp/fail ]; then echo "ERROR: unexpected exit 0!" exit 1 fi find_patterns_or_exit \ /tmp/out \ "^Error:" \ "but none of the providers can be installed" \ "conflicts with osmocom-" configure_osmocom_repo_centos_remove "$PROJ_CONFLICT" configure_osmocom_repo_centos "$PROJ" } test_conflict() { case "$DISTRO" in debian*) test_conflict_debian ;; centos*) test_conflict_centos ;; esac } filter_packages() { for i in "$@"; do case "$i" in # OpenBSC # This is legacy, we aren't really interested in testing # openbsc.git derived packages. Packages are found in # openbsc/debian/control. osmo-bsc-dev) ;; osmo-bsc-mgcp*) ;; osmocom-bs11-utils*) ;; osmocom-bsc-nat*) ;; osmocom-bsc-sccplite*) ;; osmocom-ipaccess-utils*) ;; osmocom-nitb*) ;; # Causing conflicts, not relevant for the test liblimesuite*) ;; liborcania*) ;; libulfius*) ;; libhyder*) ;; limesuite*) ;; soapysdr*-module-lms7*) ;; # Depends on specific verions 0.5.4.38.0847 of rtl-sdr, which # we won't install librtlsdr0-dbgsym) ;; rtl-sdr-dbgsym) ;; # Depends on mongodb, which was droppend from debian 10 onwards open5gs*) ;; # Dependencies that have a different name in centos8/almalinux8 # but are pulled in by linking to opensuse packages. In OBS we # work around this in the project config. ulfius-devel) ;; nftables-devel) ;; python3-nftables) ;; # All other packages are not filtered *) echo "$i" ;; esac done } install_repo_packages_debian() { local packages echo "Installing all repository packages" # Get a list of all packages from the repository. Reference: # https://www.debian.org/doc/manuals/aptitude/ch02s04s05.en.html packages="$(aptitude search -F%p \ "?origin(.*$PROJ.*) ?architecture(native)" | sort)" packages="$(filter_packages $packages)" apt-get install -y --no-install-recommends -- $packages } install_repo_packages_centos() { local packages echo "Installing all repository packages" # Get a list of all packages from the repository packages=$(LANG=C.UTF-8 repoquery \ --quiet \ --repoid="$(proj_with_underscore "$PROJ")" \ --archlist="x86_64,noarch" \ --qf="%{name}" \ | sort) packages="$(filter_packages $packages)" dnf install -y -- $packages } install_repo_packages() { case "$DISTRO" in debian*) install_repo_packages_debian ;; centos*) install_repo_packages_centos ;; esac } test_binaries_version() { # Make sure --version runs and does not output UNKNOWN failed="" for program in $@; do # Make sure it runs at all $program --version # Check for UNKNOWN if $program --version | grep -q UNKNOWN; then failed="$failed $program" echo "ERROR: this program prints UNKNOWN in --version!" fi done if [ -n "$failed" ]; then echo "ERROR: the following program(s) print UNKNOWN in --version:" echo "$failed" return 1 fi } test_binaries() { # Make sure that binares run at all and output a proper version test_binaries_version \ osmo-bsc \ osmo-bts-trx \ osmo-bts-virtual \ osmo-cbc \ osmo-e1d \ osmo-gbproxy \ osmo-ggsn \ osmo-gtphub \ osmo-hlr \ osmo-hlr-db-tool \ osmo-hnbgw \ osmo-hnodeb \ osmo-mgw \ osmo-msc \ osmo-mslookup-client \ osmo-pcap-client \ osmo-pcap-server \ osmo-pcu \ osmo-remsim-bankd \ osmo-remsim-client-shell \ osmo-remsim-client-st2 \ osmo-remsim-server \ osmo-sgsn \ osmo-sip-connector \ osmo-smlc \ osmo-stp \ osmo-trx-ipc \ osmo-trx-uhd \ osmo-uecups-daemon case "$DISTRO" in debian*) test_binaries_version \ osmo-trx-usrp1 ;; esac if [ "$DISTRO" != "debian10" ]; then test_binaries_version \ osmo-upf # OS#5817: not packaged for debian, needs osmo-upf release if [ "$FEED" = "nightly" ] || [ "$DISTRO" = "centos8" ]; then test_binaries_version \ osmo-pfcp-tool fi fi if [ "$FEED" = "nightly" ]; then test_binaries_version \ osmo-bsc-nat fi } services_check() { local service local services_feed="$SERVICES" local failed="" if [ "$FEED" = "nightly" ]; then services_feed="$services_feed $SERVICES_NIGHTLY" fi # We don't build osmo-upf for debian 10 if [ "$DISTRO" != "debian10" ]; then # osmo-upf <= 0.1.1 needs GTP kernel module if [ "$FEED" = "nightly" ]; then # osmo-upf nightly needs a newer kernel (OS#5905) # services_feed="$services_feed osmo-upf" true fi fi systemctl start $services_feed sleep 2 for service in $services_feed; do if ! systemctl --no-pager -l -n 200 status $service; then failed="$failed $service" journalctl -u "$service" -n 200 fi done systemctl stop $services_feed if [ -n "$failed" ]; then set +x echo echo "ERROR: services failed to start: $failed" echo exit 1 fi } check_env prepare_vm uname -a for test in $TESTS; do set +x echo echo "### Running test: $test ###" echo set -x case "$test" in test_conflict) test_conflict ;; install_repo_packages) install_repo_packages ;; test_binaries) # install_repo_packages must run first! test_binaries ;; services_check) # install_repo_packages must run first! services_check ;; *) echo "ERROR: unknown test: $test" exit 1 ;; esac set +x echo echo "### Test successful: $test ###" echo set -x done