├── .copr └── Makefile ├── .github └── workflows │ ├── build-tdnf-rpms.yml │ └── ci.yml ├── .gitignore ├── CMakeLists.txt ├── CONTRIBUTING.md ├── COPYING ├── README.md ├── VERSION ├── bin ├── CMakeLists.txt └── tdnf-automatic.in ├── ci ├── Dockerfile.fedora ├── Dockerfile.photon ├── build-rpms.sh ├── coverity.sh ├── docker-entrypoint.sh └── prep.sh ├── client ├── .gitignore ├── CMakeLists.txt ├── api.c ├── client.c ├── config.c ├── config.h.in ├── defines.h ├── eventdata.c ├── goal.c ├── gpgcheck.c ├── history.c ├── includes.h ├── init.c ├── packageutils.c ├── plugins.c ├── prototypes.h ├── remoterepo.c ├── repo.c ├── repolist.c ├── repoutils.c ├── resolve.c ├── rpmtrans.c ├── structs.h ├── tdnf.pc.in ├── updateinfo.c ├── utils.c └── varsdir.c ├── cmake ├── AddCCompilerFlag.cmake ├── CreatePackages.cmake ├── FindExpat.cmake ├── FindGpgme.cmake ├── FindLibSolv.cmake ├── FindOpenSSL.cmake └── FindPackageHandleStandardArgs.cmake ├── common ├── CMakeLists.txt ├── config.h ├── defines.h ├── includes.h ├── lock.c ├── log.c ├── memory.c ├── prototypes.h ├── setopt.c ├── strings.c ├── structs.h └── utils.c ├── docs └── coding-guidelines.md ├── etc ├── CMakeLists.txt ├── bash_completion.d │ ├── CMakeLists.txt │ └── tdnf-completion.bash ├── motdgen.d │ ├── 02-tdnf-updateinfo.sh │ └── CMakeLists.txt ├── systemd │ ├── CMakeLists.txt │ ├── tdnf-automatic-install.service │ ├── tdnf-automatic-install.timer │ ├── tdnf-automatic-notifyonly.service │ ├── tdnf-automatic-notifyonly.timer │ ├── tdnf-automatic.service │ └── tdnf-automatic.timer └── tdnf │ ├── CMakeLists.txt │ ├── automatic.conf │ ├── pluginconf.d │ ├── CMakeLists.txt │ ├── tdnfmetalink.conf │ └── tdnfrepogpgcheck.conf │ └── tdnf.conf ├── history ├── CMakeLists.txt ├── config.h.in ├── history.c ├── history.h └── main.c ├── include ├── tdnf-common-defines.h ├── tdnf.h ├── tdnfcli.h ├── tdnfclierror.h ├── tdnfclitypes.h ├── tdnferror.h ├── tdnfplugin.h ├── tdnfplugineventmap.h └── tdnftypes.h ├── jsondump ├── CMakeLists.txt ├── jsondump.c ├── jsondump.h └── test.c ├── llconf ├── CMakeLists.txt ├── entry.c ├── entry.h ├── ini.c ├── ini.h ├── lines.c ├── lines.h ├── modules.c ├── modules.h ├── nodes.c ├── nodes.h ├── strutils.c └── strutils.h ├── plugins ├── .gitignore ├── CMakeLists.txt ├── README.md ├── metalink │ ├── CMakeLists.txt │ ├── api.c │ ├── config.h.in │ ├── defines.h │ ├── includes.h │ ├── list.c │ ├── metalink.c │ ├── prototypes.h │ ├── structs.h │ └── utils.c └── repogpgcheck │ ├── CMakeLists.txt │ ├── api.c │ ├── config.h.in │ ├── defines.h │ ├── includes.h │ ├── prototypes.h │ ├── repogpgcheck.c │ └── structs.h ├── pytests ├── .gitignore ├── CMakeLists.txt ├── __init__.py ├── config-install.json.in ├── config.json.in ├── conftest.py ├── mount-small-cache.in ├── repo │ ├── setup-repo.sh │ ├── tdnf-bad-pre.spec │ ├── tdnf-conflict-file0.spec │ ├── tdnf-conflict-file1.spec │ ├── tdnf-dummy-pretrans.spec │ ├── tdnf-missing-dep.spec │ ├── tdnf-multi1.spec │ ├── tdnf-multi2.spec │ ├── tdnf-multi3.spec │ ├── tdnf-multi4.spec │ ├── tdnf-repoquery-base.spec │ ├── tdnf-repoquery-changelog.spec │ ├── tdnf-repoquery-deps.spec.in │ ├── tdnf-repoquery-queryformat.spec │ ├── tdnf-test-cleanreq-leaf1.spec │ ├── tdnf-test-cleanreq-leaf2.spec │ ├── tdnf-test-cleanreq-required.spec │ ├── tdnf-test-dummy-conflicts-0.spec │ ├── tdnf-test-dummy-conflicts-1.spec │ ├── tdnf-test-dummy-obsoleted.spec │ ├── tdnf-test-dummy-obsoleting.spec │ ├── tdnf-test-dummy-obsoleting3.spec │ ├── tdnf-test-dummy-requires.spec │ ├── tdnf-test-multiversion-1.0.1.spec │ ├── tdnf-test-multiversion-1.0.2.spec │ ├── tdnf-test-noarch.spec │ ├── tdnf-test-one.spec │ ├── tdnf-test-pretrans-one.spec │ ├── tdnf-test-pretrans-two.spec │ ├── tdnf-test-toolarge.spec │ ├── tdnf-test-two.spec │ ├── tdnf-verbose-scripts.spec │ ├── updateinfo-1.xml │ └── updateinfo-2.xml └── tests │ ├── test_assumeno.py │ ├── test_auth.py │ ├── test_autoremove.py │ ├── test_baseurls.py │ ├── test_cache.py │ ├── test_cfgreader.py │ ├── test_check_local.py │ ├── test_check_skip.py │ ├── test_check_update.py │ ├── test_checksum.py │ ├── test_clean.py │ ├── test_config.py │ ├── test_configutil.py │ ├── test_conflict.py │ ├── test_count.py │ ├── test_downgrade.py │ ├── test_downloadonly.py │ ├── test_erase.py │ ├── test_excludes.py │ ├── test_expired_cache.py │ ├── test_granular_perms.py │ ├── test_history.py │ ├── test_install.py │ ├── test_installroot.py │ ├── test_json.py │ ├── test_list.py │ ├── test_lock.py │ ├── test_locks.py │ ├── test_mark.py │ ├── test_metalink.py │ ├── test_minversions.py │ ├── test_mirrorlist.py │ ├── test_multiinstall.py │ ├── test_noscripts.py │ ├── test_pluginconf.py │ ├── test_pretrans.py │ ├── test_priority.py │ ├── test_protected.py │ ├── test_provides.py │ ├── test_repo_missing_metadata.py │ ├── test_repofrompath.py │ ├── test_repogpgcheck.py │ ├── test_repoid.py │ ├── test_repolist.py │ ├── test_repoquery.py │ ├── test_reposync.py │ ├── test_rpm_cmdline.py │ ├── test_rpmdefine.py │ ├── test_search.py │ ├── test_setopt_reposdir.py │ ├── test_signature.py │ ├── test_skip_md.py │ ├── test_srpms.py │ ├── test_tdnf_automatic.py │ ├── test_update.py │ ├── test_updateinfo.py │ ├── test_vars.py │ ├── test_version.py │ └── test_whatprovides.py ├── scripts ├── build-tdnf-rpms.in ├── fix-copyright.py └── llvm-tdnf-build.sh ├── solv ├── CMakeLists.txt ├── defines.h ├── includes.h ├── prototypes.h ├── simplequery.c ├── tdnfpackage.c ├── tdnfpool.c ├── tdnfquery.c └── tdnfrepo.c ├── tdnf.spec.in ├── tools ├── CMakeLists.txt ├── cli │ ├── CMakeLists.txt │ ├── defines.h │ ├── includes.h │ ├── lib │ │ ├── CMakeLists.txt │ │ ├── api.c │ │ ├── help.c │ │ ├── includes.h │ │ ├── installcmd.c │ │ ├── options.c │ │ ├── output.c │ │ ├── parseargs.c │ │ ├── parsecleanargs.c │ │ ├── parsehistoryargs.c │ │ ├── parselistargs.c │ │ ├── parserepolistargs.c │ │ ├── parserepoqueryargs.c │ │ ├── parsereposyncargs.c │ │ ├── parseupdateinfo.c │ │ ├── prototypes.h │ │ ├── tdnf-cli-libs.pc.in │ │ └── updateinfocmd.c │ ├── main.c │ └── prototypes.h └── config │ ├── CMakeLists.txt │ └── main.c └── tox.ini /.copr/Makefile: -------------------------------------------------------------------------------- 1 | THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST)))) 2 | 3 | project_dir := $(abspath $(THIS_DIR)/..) 4 | 5 | outdir ?= $(project_dir) 6 | name := tdnf 7 | spec_file := $(project_dir)/$(name).spec 8 | version := $(shell cat $(project_dir)/VERSION) 9 | tarball := $(name)-$(version).tar.gz 10 | 11 | prereq: 12 | which git || dnf -y install git 13 | 14 | spec: 15 | @echo THISDIR=$(THIS_DIR) 16 | sed s/@PROJECT_VERSION@/$(version)/g $(spec_file).in > $(spec_file) 17 | 18 | srpm: spec prereq 19 | cd $(project_dir) && \ 20 | git archive --format=tar.gz -o $(tarball) --prefix=$(name)-$(version)/ HEAD && \ 21 | rpmbuild -D'_srcrpmdir $(outdir)' -D'_sourcedir $(project_dir)' -bs $(spec_file) 22 | -------------------------------------------------------------------------------- /.github/workflows/build-tdnf-rpms.yml: -------------------------------------------------------------------------------- 1 | name: tdnf RPMs 2 | 3 | on: [pull_request, push, workflow_dispatch] 4 | 5 | jobs: 6 | photon-rpms: 7 | env: 8 | DIST: photon 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: build container 13 | working-directory: ${{ github.workspace }} 14 | run: | 15 | docker build -t ${DIST}/tdnf-build -f ci/Dockerfile.${DIST} . 16 | - name: build rpms in container 17 | working-directory: ${{ github.workspace }} 18 | run: | 19 | docker run --rm -e DIST -v$(pwd):/build -w/build ${DIST}/tdnf-build ./ci/build-rpms.sh 20 | - name: run pytests package 21 | working-directory: ${{ github.workspace }} 22 | run: | 23 | docker run --rm -v$(pwd)/rpms:/rpms ${DIST} /bin/sh -c 'tdnf -y --repofrompath=tdnf,/rpms install tdnf-pytests && pytest /usr/share/tdnf/pytests/' 24 | - name: upload RPMs 25 | uses: actions/upload-artifact@v4 26 | with: 27 | name: tdnf-rpms 28 | path: rpms 29 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: tdnf CI 2 | 3 | on: [pull_request, push, workflow_dispatch] 4 | 5 | jobs: 6 | photon: 7 | env: 8 | DIST: photon 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: build container 13 | working-directory: ${{ github.workspace }} 14 | run: | 15 | docker build -t ${DIST}/tdnf-build -f ci/Dockerfile.${DIST} . 16 | - name: run container with tests 17 | working-directory: ${{ github.workspace }} 18 | run: | 19 | docker run --privileged --security-opt seccomp:unconfined --rm -e DIST -v$(pwd):/build -w/build ${DIST}/tdnf-build ./ci/docker-entrypoint.sh 20 | fedora: 21 | env: 22 | DIST: fedora 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: build container 27 | working-directory: ${{ github.workspace }} 28 | run: | 29 | docker build -t ${DIST}/tdnf-build -f ci/Dockerfile.${DIST} . 30 | - name: run container with tests 31 | working-directory: ${{ github.workspace }} 32 | run: | 33 | docker run --security-opt seccomp:unconfined --rm -e DIST -v$(pwd):/build -w/build ${DIST}/tdnf-build ./ci/docker-entrypoint.sh 34 | 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # automake 2 | 3 | Makefile.in 4 | 5 | *.guess 6 | *.sub 7 | *.status 8 | *.log 9 | *.pc 10 | *.patch 11 | *.diff 12 | 13 | tags 14 | 15 | # autoconf 16 | /autom4te.cache 17 | /aclocal.m4 18 | /compile 19 | /configure 20 | /depcomp 21 | /install-sh 22 | /missing 23 | /stamp-h1 24 | /m4 25 | ltmain.sh 26 | libtool 27 | ar-lib 28 | 29 | /solv/.deps 30 | /solv/.libs 31 | /common/.deps 32 | /common/.libs 33 | /client/.deps 34 | /client/.libs 35 | /tools/cli/.deps 36 | /tools/cli/.libs 37 | /tools/cli/tdnf 38 | /tools/cli/lib/.deps 39 | /tools/cli/lib/.libs 40 | /tests/atconfig 41 | /tests/testsuite 42 | /tests/package.m4 43 | tests/testroot/ 44 | tests/testsuite.dir/ 45 | /python/.deps 46 | /python/.libs 47 | /python/setup.py 48 | __pycache__/ 49 | .pytest_cache/ 50 | 51 | # Object files 52 | *.o 53 | *.ko 54 | *.obj 55 | *.elf 56 | 57 | # Precompiled Headers 58 | *.gch 59 | *.pch 60 | 61 | # Libraries 62 | *.lib 63 | *.a 64 | *.la 65 | *.lo 66 | 67 | # Shared objects (inc. Windows DLLs) 68 | *.dll 69 | *.so 70 | *.so.* 71 | *.dylib 72 | 73 | # Executables 74 | *.exe 75 | *.out 76 | *.app 77 | *.i*86 78 | *.x86_64 79 | *.hex 80 | 81 | #generated files 82 | *.pc 83 | 84 | # build directory 85 | build*/ 86 | bin/tdnf 87 | 88 | # cmake files 89 | *.cmake 90 | CMakeFiles/ 91 | CMakeCache.txt 92 | 93 | # cores 94 | core* 95 | 96 | # vi backup 97 | *.swp 98 | 99 | # Apple forks 100 | ._* 101 | 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tdnf - tiny dandified yum 2 | 3 | In order to compile, from the checkout directory, run the following 4 | 5 | ```sh 6 | mkdir build && cd build 7 | cmake .. 8 | make 9 | ``` 10 | 11 | Do enable debugging symbols (useful for use with `gdb`), use: 12 | ``` 13 | cmake -DCMAKE_BUILD_TYPE=Debug .. 14 | ``` 15 | 16 | You can also build tdnf using docker using the following commands: 17 | 18 | ```sh 19 | docker build -t photon/tdnf-build -f ci/Dockerfile.photon . 20 | docker run --rm -it -v $(pwd):/build -w /build photon/tdnf-build 21 | ``` 22 | 23 | create a conf file named `tdnf.conf` under `/etc/tdnf/` with the following content 24 | 25 | ```text 26 | [main] 27 | gpgcheck=1 28 | installonly_limit=3 29 | clean_requirements_on_remove=true 30 | repodir=/etc/yum.repos.d 31 | cachedir=/var/cache/tdnf 32 | ``` 33 | 34 | Now configure repo files under `/etc/yum.repos.d` or your repodir following 35 | `.repo` format of dnf/yum. 36 | 37 | You should now have a client executable named tdnf under `bin/`. To test 38 | run: 39 | 40 | ```sh 41 | ./bin/tdnf list installed 42 | ``` 43 | 44 | You should see a list of installed packages and their related info 45 | 46 | ## Testing 47 | 48 | To build and run the test scripts within a container, do: 49 | 50 | ```text 51 | export DIST=photon 52 | docker run --security-opt seccomp:unconfined --rm -it -e DIST -v$(pwd):/build -w/build ${DIST}/tdnf-build ./ci/docker-entrypoint.sh 53 | ``` 54 | Same for 55 | ```text 56 | export DIST=fedora 57 | ``` 58 | 59 | ## Coverity 60 | 61 | Assuming you have coverity installed on `/pathto/coverity`, you can run: 62 | 63 | ```text 64 | docker run --rm -it -v $(pwd):/build -v /pathto/coverity/:/coverity/ -w /build photon/tdnf-build ./ci/coverity.sh 65 | ``` 66 | 67 | This will put the output to `./build-coverity`. You can then commit the results to the coverity database from that directory, or view the results in `./build-coverity/html`. For example, you can start an nginx container: 68 | 69 | ```text 70 | docker run -it --rm -p 8080:80 --name web -v $(pwd)/build-coverity/html:/usr/share/nginx/html nginx 71 | ``` 72 | and then view results in your browser at `http://:8080/`. 73 | 74 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 3.6.0 2 | -------------------------------------------------------------------------------- /bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | install(PROGRAMS "tdnf-automatic" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT binary) 10 | -------------------------------------------------------------------------------- /ci/Dockerfile.fedora: -------------------------------------------------------------------------------- 1 | FROM fedora:latest 2 | 3 | COPY ci/prep.sh /prep.sh 4 | RUN chmod +x /prep.sh 5 | RUN /prep.sh 6 | 7 | CMD ["/bin/bash"] 8 | -------------------------------------------------------------------------------- /ci/Dockerfile.photon: -------------------------------------------------------------------------------- 1 | FROM photon:latest 2 | 3 | COPY ci/prep.sh /prep.sh 4 | RUN chmod +x /prep.sh 5 | RUN /prep.sh 6 | 7 | CMD ["/bin/bash"] 8 | -------------------------------------------------------------------------------- /ci/build-rpms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | rpmdir=${1:-rpms} 5 | 6 | rm -rf build 7 | mkdir -p build 8 | 9 | pushd build 10 | cmake .. && ../scripts/build-tdnf-rpms ${rpmdir} 11 | popd 12 | 13 | createrepo ${rpmdir} 14 | -------------------------------------------------------------------------------- /ci/coverity.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | COVERITY_BIN=/coverity/bin/ 4 | export PATH=${COVERITY_BIN}:${PATH} 5 | 6 | COVERITY_DIR=build-coverity 7 | rm -rf ${COVERITY_DIR} 8 | mkdir -p ${COVERITY_DIR} 9 | cd ${COVERITY_DIR} 10 | 11 | cmake .. 12 | 13 | COV_CONFIG=coverity-config.xml 14 | COV_DIR=coverity-intermediate 15 | CC=cc 16 | 17 | cov-configure --config ${COV_CONFIG} --compiler ${CC} --comptype gcc --template 18 | cov-build --dir ${COV_DIR} --config ${COV_CONFIG} make 19 | 20 | # gcc >= 10.0 workaround, see https://www.mail-archive.com/gcc@gcc.gnu.org/msg93814.html 21 | #if grep -qr 'version>0' . --include=*.xml ; then 22 | # for f in $(grep -lr 'version>0' . --include=*.xml) ; do sed -i 's/version>0/version>10/' $f; done 23 | # make clean 24 | # cov-build --dir ${COV_DIR} --config ${COV_CONFIG} make 25 | #fi 26 | 27 | cov-analyze --dir ${COV_DIR} --config ${COV_CONFIG} --all 28 | 29 | mkdir html 30 | cov-format-errors --dir ${COV_DIR} --html-output html 31 | 32 | -------------------------------------------------------------------------------- /ci/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm -rf build 6 | mkdir -p build 7 | cd build || exit 1 8 | 9 | JOBS=$(( ($(nproc)+1) / 2 )) 10 | HIST_DB_DIR="/usr/lib/sysimage/tdnf" 11 | 12 | { 13 | mkdir -p ${HIST_DB_DIR} 14 | cmake -DHISTORY_DB_DIR=${HIST_DB_DIR} .. 15 | make -j${JOBS} 16 | make check -j${JOBS} 17 | } || exit 1 18 | 19 | if ! flake8 ../pytests ; then 20 | echo "ERROR: flake8 tests failed" >&2 21 | exit 1 22 | fi 23 | -------------------------------------------------------------------------------- /ci/prep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | rel_file="/etc/os-release" 6 | 7 | common_pkgs=( 8 | cmake 9 | createrepo_c 10 | e2fsprogs 11 | expat-devel 12 | findutils 13 | gpgme-devel 14 | libsolv-devel 15 | openssl-devel 16 | popt-devel 17 | python3-devel 18 | python3-pip 19 | python3-pyOpenSSL 20 | python3-pytest 21 | python3-requests 22 | python3-setuptools 23 | python3-urllib3 24 | rpm-build 25 | sed 26 | sqlite-devel 27 | sudo 28 | util-linux 29 | valgrind 30 | which 31 | ) 32 | 33 | if grep -qw "Fedora" ${rel_file}; then 34 | fedora_packages=( 35 | ${common_pkgs[@]} 36 | gcc 37 | glib2-devel 38 | libcurl-devel 39 | make 40 | python3-flake8 41 | rpm-devel 42 | rpm-sign 43 | shadow-utils 44 | ) 45 | dnf -y upgrade --refresh 46 | dnf -y install ${fedora_packages[@]} 47 | elif grep -qw "Photon" ${rel_file}; then 48 | photon_packages=( 49 | ${common_pkgs[@]} 50 | build-essential 51 | curl-devel 52 | glib 53 | glibc-debuginfo 54 | shadow 55 | zlib-devel 56 | ) 57 | tdnf -y upgrade --refresh 58 | tdnf remove -y toybox 59 | tdnf -y install --enablerepo=photon-debuginfo ${photon_packages[@]} 60 | pip3 install flake8 61 | fi 62 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | config.h 2 | -------------------------------------------------------------------------------- /client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | include_directories(${CMAKE_SOURCE_DIR}/include) 10 | 11 | #make config.h with 12 | #PACKAGE_NAME and PACKAGE_VERSION defined 13 | configure_file( 14 | config.h.in 15 | ${CMAKE_CURRENT_SOURCE_DIR}/config.h @ONLY 16 | ) 17 | 18 | # configure pkgconfig file 19 | configure_file( 20 | tdnf.pc.in 21 | tdnf.pc @ONLY 22 | ) 23 | 24 | add_library(${LIB_TDNF} SHARED 25 | api.c 26 | client.c 27 | config.c 28 | eventdata.c 29 | goal.c 30 | gpgcheck.c 31 | init.c 32 | packageutils.c 33 | plugins.c 34 | repo.c 35 | repoutils.c 36 | remoterepo.c 37 | repolist.c 38 | resolve.c 39 | rpmtrans.c 40 | updateinfo.c 41 | utils.c 42 | history.c 43 | varsdir.c 44 | ) 45 | 46 | target_link_libraries(${LIB_TDNF} 47 | ${LIB_TDNF_COMMON} 48 | ${LIB_TDNF_SOLV} 49 | ${LIB_TDNF_HISTORY} 50 | ${LIB_TDNF_LLCONF} 51 | ${RPM_LIBRARIES} 52 | ${LibSolv_LIBRARIES} 53 | ${CURL_LIBRARIES} 54 | ${OPENSSL_LIBRARIES} 55 | ${SQLITE3_LIBRARIES} 56 | ) 57 | 58 | set_target_properties(${LIB_TDNF} PROPERTIES 59 | VERSION ${PROJECT_VERSION} 60 | SOVERSION ${PROJECT_VERSION_MAJOR} 61 | ) 62 | 63 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdnf.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 64 | install(TARGETS ${LIB_TDNF} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library) 65 | -------------------------------------------------------------------------------- /client/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PACKAGE_NAME "@PROJECT_NAME@" 4 | #define PACKAGE_VERSION "@VERSION@" 5 | 6 | /* Platform defines */ 7 | #define SYSTEM_LIBDIR "@CMAKE_INSTALL_FULL_LIBDIR@" 8 | -------------------------------------------------------------------------------- /client/history.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | uint32_t 12 | TDNFGetHistoryCtx( 13 | PTDNF pTdnf, 14 | struct history_ctx **ppCtx, 15 | int nMustExist 16 | ) 17 | { 18 | uint32_t dwError = 0; 19 | char *pszDataDir = NULL; 20 | char *pszHistoryDb = NULL; 21 | struct history_ctx *ctx = NULL; 22 | 23 | if(!pTdnf || !ppCtx) 24 | { 25 | dwError = ERROR_TDNF_INVALID_PARAMETER; 26 | BAIL_ON_TDNF_ERROR(dwError); 27 | } 28 | 29 | dwError = TDNFJoinPath(&pszDataDir, 30 | pTdnf->pArgs->pszInstallRoot, 31 | pTdnf->pConf->pszPersistDir, 32 | NULL); 33 | BAIL_ON_TDNF_ERROR(dwError); 34 | 35 | dwError = TDNFJoinPath(&pszHistoryDb, 36 | pszDataDir, 37 | HISTORY_DB_FILE, 38 | NULL); 39 | BAIL_ON_TDNF_ERROR(dwError); 40 | 41 | if (nMustExist) 42 | { 43 | int nExists = 0; 44 | dwError = TDNFIsFileOrSymlink(pszHistoryDb, &nExists); 45 | BAIL_ON_TDNF_ERROR(dwError); 46 | if (!nExists) 47 | { 48 | dwError = ERROR_TDNF_HISTORY_NODB; 49 | BAIL_ON_TDNF_ERROR(dwError); 50 | } 51 | } 52 | 53 | dwError = TDNFUtilsMakeDirs(pszDataDir); 54 | if (dwError == ERROR_TDNF_ALREADY_EXISTS) 55 | { 56 | dwError = 0; 57 | } 58 | BAIL_ON_TDNF_ERROR(dwError); 59 | 60 | ctx = create_history_ctx(pszHistoryDb); 61 | if (ctx == NULL) 62 | { 63 | dwError = ERROR_TDNF_HISTORY_ERROR; 64 | BAIL_ON_TDNF_ERROR(dwError); 65 | } 66 | 67 | *ppCtx = ctx; 68 | 69 | cleanup: 70 | TDNF_SAFE_FREE_MEMORY(pszDataDir); 71 | TDNF_SAFE_FREE_MEMORY(pszHistoryDb); 72 | return dwError; 73 | error: 74 | goto cleanup; 75 | } 76 | -------------------------------------------------------------------------------- /client/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __CLIENT_INCLUDES_H__ 10 | #define __CLIENT_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "../solv/includes.h" 36 | 37 | //librpm 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | //libcurl 49 | #include 50 | 51 | #include "../history/history.h" 52 | 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | #include "defines.h" 59 | #include "structs.h" 60 | #include "../common/config.h" 61 | #include "../common/structs.h" 62 | #include "../common/prototypes.h" 63 | #include "prototypes.h" 64 | 65 | #include "config.h" 66 | 67 | #endif /* __CLIENT_INCLUDES_H__ */ 68 | -------------------------------------------------------------------------------- /client/structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | typedef struct _TDNF_PLUGIN_ 12 | { 13 | char *pszName; 14 | int nEnabled; 15 | void *pModule; 16 | PTDNF_PLUGIN_HANDLE pHandle; 17 | TDNF_PLUGIN_EVENT RegisterdEvts; 18 | TDNF_PLUGIN_INTERFACE stInterface; 19 | struct _TDNF_PLUGIN_ *pNext; 20 | } TDNF_PLUGIN; 21 | 22 | typedef struct _TDNF_ 23 | { 24 | PSolvSack pSack; 25 | PTDNF_CMD_ARGS pArgs; 26 | PTDNF_CONF pConf; 27 | PTDNF_REPO_DATA pRepos; 28 | Repo *pSolvCmdLineRepo; 29 | PTDNF_PLUGIN pPlugins; 30 | } TDNF; 31 | 32 | typedef struct _TDNF_CACHED_RPM_ENTRY 33 | { 34 | char* pszFilePath; 35 | struct _TDNF_CACHED_RPM_ENTRY *pNext; 36 | } TDNF_CACHED_RPM_ENTRY, *PTDNF_CACHED_RPM_ENTRY; 37 | 38 | typedef struct _TDNF_CACHED_RPM_LIST 39 | { 40 | int nSize; 41 | PTDNF_CACHED_RPM_ENTRY pHead; 42 | } TDNF_CACHED_RPM_LIST, *PTDNF_CACHED_RPM_LIST; 43 | 44 | typedef struct _TDNF_RPM_TS_ 45 | { 46 | int nQuiet; 47 | rpmts pTS; 48 | rpmtransFlags nTransFlags; 49 | rpmprobFilterFlags nProbFilterFlags; 50 | FD_t pFD; 51 | PTDNF_CACHED_RPM_LIST pCachedRpmsArray; 52 | } TDNFRPMTS, *PTDNFRPMTS; 53 | 54 | typedef struct _TDNF_REPO_METADATA 55 | { 56 | char *pszRepoCacheDir; 57 | char *pszRepo; 58 | char *pszRepoMD; 59 | char *pszPrimary; 60 | char *pszFileLists; 61 | char *pszUpdateInfo; 62 | char *pszOther; 63 | } TDNF_REPO_METADATA,*PTDNF_REPO_METADATA; 64 | 65 | typedef struct _TDNF_EVENT_DATA_ 66 | { 67 | union 68 | { 69 | int nInt; 70 | const char *pcszStr; 71 | const void *pPtr; 72 | }; 73 | TDNF_EVENT_ITEM_TYPE nType; 74 | const char *pcszName; 75 | struct _TDNF_EVENT_DATA_ *pNext; 76 | } TDNF_EVENT_DATA; 77 | 78 | typedef struct progress_cb_data { 79 | time_t cur_time; 80 | time_t prev_time; 81 | char pszData[64]; 82 | } pcb_data; 83 | -------------------------------------------------------------------------------- /client/tdnf.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/include/tdnf 4 | 5 | Name: tdnf 6 | Description: Tiny Dandified YUM 7 | Version: @PROJECT_VERSION@ 8 | Provides: libtdnf = @PROJECT_VERSION@ 9 | Requires: libsolv libsolvext rpm libcurl 10 | Libs: -L${libdir} -ltdnf 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /cmake/AddCCompilerFlag.cmake: -------------------------------------------------------------------------------- 1 | # - Adds a compiler flag if it is supported by the compiler 2 | # 3 | # This function checks that the supplied compiler flag is supported and then 4 | # adds it to the corresponding compiler flags 5 | # 6 | # add_c_compiler_flag( []) 7 | # 8 | # - Example 9 | # 10 | # include(AddCCompilerFlag) 11 | # add_c_compiler_flag(-Wall) 12 | # add_c_compiler_flag(-no-strict-aliasing RELEASE) 13 | # Requires CMake 2.6+ 14 | 15 | if(__add_c_compiler_flag) 16 | return() 17 | endif() 18 | 19 | set(__add_c_compiler_flag INCLUDED) 20 | 21 | include(CheckCCompilerFlag) 22 | 23 | function(add_c_compiler_flag FLAG) 24 | string(TOUPPER "HAVE_C_FLAG_${FLAG}" SANITIZED_FLAG) 25 | string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG}) 26 | string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) 27 | string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) 28 | set(CMAKE_REQUIRED_FLAGS "${FLAG}") 29 | check_c_compiler_flag("" ${SANITIZED_FLAG}) 30 | if(${SANITIZED_FLAG}) 31 | set(VARIANT ${ARGV1}) 32 | if(ARGV1) 33 | string(REGEX REPLACE "[^A-Za-z_0-9]" "_" VARIANT "${VARIANT}") 34 | string(TOUPPER "_${VARIANT}" VARIANT) 35 | endif() 36 | set(CMAKE_C_FLAGS${VARIANT} "${CMAKE_C_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) 37 | endif() 38 | endfunction() 39 | -------------------------------------------------------------------------------- /cmake/CreatePackages.cmake: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") 2 | message(FATAL_ERROR "Cpack module is not present!") 3 | endif() 4 | 5 | set(CPACK_PACKAGE_NAME "tdnf") 6 | set(CPACK_PACKAGE_VENDOR "VMware, Inc.") 7 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "tdnf is a yum/dnf equivalent which uses libsolv and libcurl") 8 | set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") 9 | set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) 10 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") 11 | 12 | set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}") 13 | #set(CPACK_RPM_PACKAGE_ARCHITECTURE "noarch") 14 | set(CPACK_GENERATOR "RPM") 15 | 16 | set(CPACK_SOURCE_GENERATOR "TGZ") 17 | set(CPACK_SOURCE_IGNORE_FILES 18 | /.git 19 | .travis.yml 20 | /ci/* 21 | .pytest_cache/* 22 | __pycache__/* 23 | /build* 24 | ) 25 | 26 | #set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/pre.sh") 27 | #set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/post.sh") 28 | include(CPack) 29 | 30 | -------------------------------------------------------------------------------- /cmake/FindExpat.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find expat 2 | # Once done this will define 3 | # EXPAT_INCLUDE_DIRS - The expat include directories 4 | # EXPAT_LIBRARIES - The libraries needed to use expat-devel 5 | 6 | find_path(EXPAT_INCLUDE_DIR expat.h) 7 | find_library(EXPAT_LIBRARY NAMES libexpat.so) 8 | 9 | find_package_handle_standard_args(expat DEFAULT_MSG 10 | EXPAT_LIBRARY EXPAT_INCLUDE_DIR) 11 | 12 | set(EXPAT_LIBRARIES ${EXPAT_LIBRARY}) 13 | set(EXPAT_INCLUDE_DIRS ${EXPAT_INCLUDE_DIR}) 14 | -------------------------------------------------------------------------------- /cmake/FindGpgme.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find gpgme 2 | # Once done this will define 3 | # GPGME_FOUND - System has gpgme 4 | # GPGME_INCLUDE_DIRS - The gpgme include directories 5 | # GPGME_LIBRARIES - The libraries needed to use gpgme 6 | 7 | find_path(GPGME_INCLUDE_DIR gpgme.h) 8 | 9 | find_library(GPGME_LIBRARY NAMES gpgme) 10 | 11 | # handle the QUIETLY and REQUIRED arguments and set GPGME_FOUND to TRUE 12 | # if all listed variables are TRUE 13 | find_package_handle_standard_args(gpgme DEFAULT_MSG 14 | GPGME_LIBRARY GPGME_INCLUDE_DIR) 15 | 16 | mark_as_advanced(GPGME_INCLUDE_DIR GPGME_LIBRARY ) 17 | 18 | set(GPGME_LIBRARIES ${GPGME_LIBRARY} ) 19 | set(GPGME_INCLUDE_DIRS ${GPGME_INCLUDE_DIR} ) 20 | 21 | -------------------------------------------------------------------------------- /cmake/FindOpenSSL.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find openssl 2 | # Once done this will define 3 | # OPENSSL_INCLUDE_DIRS - The openssl include directories 4 | # OPENSSL_LIBRARIES - The libraries needed to use openssl-devel 5 | 6 | find_path(OPENSSL_INCLUDE_DIR openssl/sha.h) 7 | find_library(OPENSSL_LIBRARY NAMES libssl.so) 8 | 9 | find_package_handle_standard_args(libssl DEFAULT_MSG 10 | OPENSSL_LIBRARY OPENSSL_INCLUDE_DIR) 11 | 12 | set(OPENSSL_LIBRARIES ${OPENSSL_LIBRARY}) 13 | set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR}) 14 | -------------------------------------------------------------------------------- /common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | include_directories(${CMAKE_SOURCE_DIR}/include) 10 | 11 | add_library(${LIB_TDNF_COMMON} STATIC 12 | memory.c 13 | setopt.c 14 | strings.c 15 | utils.c 16 | log.c 17 | lock.c 18 | ) 19 | -------------------------------------------------------------------------------- /common/defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | #define STRINGIFYX(N) STRINGIFY(N) 12 | #define STRINGIFY(N) #N 13 | 14 | #define MAX_CONFIG_LINE_LENGTH 1024 15 | 16 | #define TDNF_SAFE_FREE_PKGINFO(pPkgInfo) \ 17 | do { \ 18 | if (pPkgInfo) { \ 19 | TDNFFreePackageInfo(pPkgInfo); \ 20 | } \ 21 | } while(0) 22 | 23 | #define TDNF_DEFAULT_MAX_STRING_LEN 16384000 24 | 25 | /* 26 | * creating this under /var/run because /var/run/lock doesn't exist 27 | * in fedora docker images and as a result ci fails 28 | */ 29 | #define TDNF_INSTANCE_LOCK_FILE "/var/run/.tdnf-instance-lockfile" 30 | -------------------------------------------------------------------------------- /common/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __COMMON_INCLUDES_H__ 10 | #define __COMMON_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "defines.h" 31 | #include "structs.h" 32 | #include "prototypes.h" 33 | 34 | #endif /* __COMMON_INCLUDES_H__ */ 35 | -------------------------------------------------------------------------------- /common/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | static bool isQuiet = false; 12 | static bool isJson = false; 13 | static bool isDnfCheckUpdateCompat = false; 14 | 15 | void GlobalSetQuiet(int32_t val) 16 | { 17 | if (val > 0) 18 | { 19 | isQuiet = true; 20 | } 21 | } 22 | 23 | void GlobalSetJson(int32_t val) 24 | { 25 | if (val > 0) 26 | { 27 | isJson = true; 28 | } 29 | } 30 | 31 | void GlobalSetDnfCheckUpdateCompat(int32_t val) 32 | { 33 | if (val > 0) 34 | { 35 | isDnfCheckUpdateCompat = true; 36 | } 37 | } 38 | 39 | bool GlobalGetDnfCheckUpdateCompat() 40 | { 41 | return isDnfCheckUpdateCompat; 42 | } 43 | 44 | void log_console(int32_t loglevel, const char *format, ...) 45 | { 46 | va_list args; 47 | FILE *stream = NULL; 48 | 49 | if (!format) 50 | { 51 | return; 52 | } 53 | 54 | va_start(args, format); 55 | 56 | switch (loglevel) 57 | { 58 | case LOG_INFO: 59 | case LOG_CRIT: 60 | if (isJson) 61 | { 62 | goto end; 63 | } 64 | if (loglevel == LOG_INFO && isQuiet) 65 | { 66 | goto end; 67 | } 68 | stream = stdout; 69 | break; 70 | 71 | case LOG_ERR: 72 | stream = stderr; 73 | break; 74 | 75 | default: 76 | goto end; 77 | } 78 | 79 | if (!stream) 80 | { 81 | /* just in case */ 82 | goto end; 83 | } 84 | 85 | vfprintf(stream, format, args); 86 | fflush(stream); 87 | end: 88 | va_end(args); 89 | } 90 | -------------------------------------------------------------------------------- /common/memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2021 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | uint32_t 12 | TDNFAllocateMemory( 13 | size_t nNumElements, 14 | size_t nSize, 15 | void** ppMemory 16 | ) 17 | { 18 | uint32_t dwError = 0; 19 | void* pMemory = NULL; 20 | 21 | if (!ppMemory || !nSize || !nNumElements) 22 | { 23 | dwError = ERROR_TDNF_INVALID_PARAMETER; 24 | BAIL_ON_TDNF_ERROR(dwError); 25 | } 26 | 27 | if(nNumElements > SIZE_MAX/nSize) 28 | { 29 | dwError = ERROR_TDNF_INVALID_ALLOCSIZE; 30 | BAIL_ON_TDNF_ERROR(dwError); 31 | } 32 | 33 | pMemory = calloc(nNumElements, nSize); 34 | if (!pMemory) 35 | { 36 | dwError = ERROR_TDNF_OUT_OF_MEMORY; 37 | BAIL_ON_TDNF_ERROR(dwError); 38 | } 39 | 40 | *ppMemory = pMemory; 41 | 42 | cleanup: 43 | return dwError; 44 | 45 | error: 46 | if (ppMemory) 47 | { 48 | *ppMemory = NULL; 49 | } 50 | TDNF_SAFE_FREE_MEMORY(pMemory); 51 | goto cleanup; 52 | } 53 | 54 | uint32_t 55 | TDNFReAllocateMemory( 56 | size_t nSize, 57 | void** ppMemory 58 | ) 59 | { 60 | uint32_t dwError = 0; 61 | void* pMemory = NULL; 62 | 63 | if (!ppMemory || !nSize) 64 | { 65 | dwError = ERROR_TDNF_INVALID_PARAMETER; 66 | BAIL_ON_TDNF_ERROR(dwError); 67 | } 68 | 69 | pMemory = realloc(*ppMemory, nSize); 70 | if (!pMemory) 71 | { 72 | dwError = ERROR_TDNF_OUT_OF_MEMORY; 73 | BAIL_ON_TDNF_ERROR(dwError); 74 | } 75 | 76 | *ppMemory = pMemory; 77 | 78 | cleanup: 79 | return dwError; 80 | 81 | error: 82 | if (ppMemory) 83 | { 84 | *ppMemory = NULL; 85 | } 86 | TDNF_SAFE_FREE_MEMORY(pMemory); 87 | goto cleanup; 88 | } 89 | 90 | void 91 | TDNFFreeMemory( 92 | void* pMemory 93 | ) 94 | { 95 | if (pMemory) 96 | { 97 | free(pMemory); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /common/structs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct _KEYVALUE_ 8 | { 9 | char *pszKey; 10 | char *pszValue; 11 | struct _KEYVALUE_ *pNext; 12 | }KEYVALUE, *PKEYVALUE; 13 | 14 | typedef struct _CONF_SECTION_ 15 | { 16 | char *pszName; 17 | PKEYVALUE pKeyValues; 18 | struct _CONF_SECTION_ *pNext; 19 | }CONF_SECTION, *PCONF_SECTION; 20 | 21 | typedef struct _CONF_DATA_ 22 | { 23 | char *pszConfFile; 24 | PCONF_SECTION pSections; 25 | }CONF_DATA, *PCONF_DATA; 26 | 27 | typedef uint32_t 28 | (*PFN_CONF_SECTION_CB)( 29 | PCONF_DATA pData, 30 | const char *pszSection 31 | ); 32 | 33 | typedef uint32_t 34 | (*PFN_CONF_KEYVALUE_CB)( 35 | PCONF_DATA pData, 36 | const char *pszKey, 37 | const char *pszValue 38 | ); 39 | 40 | typedef struct tdnflock_s { 41 | int fd; 42 | int openmode; 43 | char *path; 44 | char *descr; 45 | int fdrefs; 46 | } *tdnflock; 47 | 48 | enum { 49 | TDNFLOCK_READ = 1 << 0, 50 | TDNFLOCK_WRITE = 1 << 1, 51 | TDNFLOCK_WAIT = 1 << 2, 52 | }; 53 | 54 | // Enum in order of preference 55 | enum { 56 | TDNF_HASH_MD5 = 0, 57 | TDNF_HASH_SHA1, 58 | TDNF_HASH_SHA256, 59 | TDNF_HASH_SHA512, 60 | TDNF_HASH_SENTINEL 61 | }; 62 | 63 | typedef struct _hash_op { 64 | char *hash_type; 65 | unsigned int length; 66 | } hash_op; 67 | 68 | typedef struct _hash_type { 69 | char *hash_name; 70 | unsigned int hash_value; 71 | }hash_type; 72 | 73 | extern hash_op hash_ops[TDNF_HASH_SENTINEL]; 74 | 75 | extern hash_type hashType[7]; 76 | -------------------------------------------------------------------------------- /etc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | ADD_SUBDIRECTORY (tdnf) 10 | ADD_SUBDIRECTORY (systemd) 11 | ADD_SUBDIRECTORY (motdgen.d) 12 | ADD_SUBDIRECTORY (bash_completion.d) 13 | -------------------------------------------------------------------------------- /etc/bash_completion.d/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | install(DIRECTORY DESTINATION "share/bash-completion/completions") 10 | install(FILES "tdnf-completion.bash" 11 | DESTINATION "${CMAKE_INSTALL_DATADIR}/bash-completion/completions" 12 | RENAME "tdnf" 13 | COMPONENT etc 14 | ) 15 | -------------------------------------------------------------------------------- /etc/motdgen.d/02-tdnf-updateinfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 5 | # Copyright (C) 2024, Broadcom, Inc. All Rights Reserved. 6 | # 7 | # Licensed under the GNU General Public License v2 (the "License"); 8 | # you may not use this file except in compliance with the License. The terms 9 | # of the License are located in the COPYING file of this distribution. 10 | # 11 | 12 | path="/var/cache/tdnf/cached-updateinfo.txt" 13 | 14 | tdnf -q --refresh updateinfo | grep -vE '^Refreshing|^Disabling' > "${path}" 15 | 16 | if [ -s "${path}" ]; then 17 | grep -qE 'Security|Bugfix|Enhancement' "${path}" || exit 0 18 | echo 19 | cat "${path}" 20 | echo "Run 'tdnf updateinfo info' to see the details." 21 | else 22 | echo "tdnf update info not available yet!" 23 | fi 24 | -------------------------------------------------------------------------------- /etc/motdgen.d/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | install(FILES "02-tdnf-updateinfo.sh" 10 | DESTINATION "${MOTGEN_DIR}" 11 | COMPONENT etc 12 | ) 13 | -------------------------------------------------------------------------------- /etc/systemd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | SET (systemd_FILES 10 | tdnf-automatic.service 11 | tdnf-automatic.timer 12 | tdnf-automatic-notifyonly.service 13 | tdnf-automatic-notifyonly.timer 14 | tdnf-automatic-install.service 15 | tdnf-automatic-install.service 16 | tdnf-automatic-install.timer) 17 | 18 | INSTALL (FILES ${systemd_FILES} DESTINATION ${SYSTEMD_DIR}) 19 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic-install.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf automatic install updates 3 | ConditionPathExists=!/run/ostree-booted 4 | After=network-online.target 5 | 6 | [Service] 7 | Type=oneshot 8 | Nice=19 9 | IOSchedulingClass=2 10 | IOSchedulingPriority=7 11 | ExecStart=/usr/bin/tdnf-automatic -c /etc/tdnf/automatic.conf --timer --install 12 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic-install.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf-automatic-install timer 3 | ConditionPathExists=!/run/ostree-booted 4 | Wants=network-online.target 5 | 6 | [Timer] 7 | OnCalendar=*-*-* 6:00 8 | RandomizedDelaySec=60m 9 | Persistent=true 10 | 11 | [Install] 12 | WantedBy=timers.target 13 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic-notifyonly.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf automatic notification of updates 3 | ConditionPathExists=!/run/ostree-booted 4 | After=network-online.target 5 | 6 | [Service] 7 | Type=oneshot 8 | Nice=19 9 | IOSchedulingClass=2 10 | IOSchedulingPriority=7 11 | ExecStart=/usr/bin/tdnf-automatic -c /etc/tdnf/automatic.conf --timer --notify 12 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic-notifyonly.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf-automatic-notifyonly timer 3 | ConditionPathExists=!/run/ostree-booted 4 | Wants=network-online.target 5 | 6 | [Timer] 7 | OnCalendar=*-*-* 6:00 8 | RandomizedDelaySec=60m 9 | Persistent=true 10 | 11 | [Install] 12 | WantedBy=timers.target 13 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf automatic 3 | ConditionPathExists=!/run/ostree-booted 4 | After=network-online.target 5 | 6 | [Service] 7 | Type=oneshot 8 | Nice=19 9 | IOSchedulingClass=2 10 | IOSchedulingPriority=7 11 | ExecStart=/usr/bin/tdnf-automatic -c /etc/tdnf/automatic.conf --timer 12 | -------------------------------------------------------------------------------- /etc/systemd/tdnf-automatic.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tdnf-automatic timer 3 | ConditionPathExists=!/run/ostree-booted 4 | Wants=network-online.target 5 | 6 | [Timer] 7 | OnCalendar=*-*-* 6:00 8 | RandomizedDelaySec=60m 9 | Persistent=true 10 | 11 | [Install] 12 | WantedBy=timers.target 13 | -------------------------------------------------------------------------------- /etc/tdnf/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | ADD_SUBDIRECTORY (pluginconf.d) 10 | 11 | install(FILES "tdnf.conf" "automatic.conf" 12 | DESTINATION "${SYSCONFDIR}/tdnf" 13 | COMPONENT etc 14 | ) 15 | 16 | install(FILES "automatic.conf" 17 | DESTINATION ${CMAKE_INSTALL_DATADIR}/tdnf/pytests/repo 18 | ) 19 | -------------------------------------------------------------------------------- /etc/tdnf/automatic.conf: -------------------------------------------------------------------------------- 1 | [commands] 2 | # What kind of upgrade to perform: 3 | # all = all available upgrades 4 | # security = only the security upgrades 5 | upgrade_type = all 6 | 7 | # random sleep duration before starting the job 8 | random_sleep = 120 9 | 10 | # Maximum time in seconds to wait until the system is online and able to 11 | # connect to remote repositories. 12 | network_online_timeout = 300 13 | 14 | # To just receive updates use tdnf-automatic-notifyonly.timer 15 | show_updates = yes 16 | 17 | # Whether updates should be applied when they are available by tdnf-automatic.timer? 18 | # tdnf-notifyonly.timer & tdnf-install.timer override this setting. 19 | apply_updates = no 20 | 21 | [emitter] 22 | # Name to use for this system in messages that are emitted. 23 | # Default is the hostname. 24 | # system_name = my-host 25 | 26 | # How to send messages. Valid options are stdio & file path 27 | # 28 | # If emit_to includes stdio, messages will be sent to stdout; 29 | # which can be seen using journalctl 30 | # 31 | # Default is stdio. 32 | emit_to_stdio = yes 33 | #emit_to_file = 34 | 35 | [base] 36 | # absolute path of tdnf config file, if not set defaults to /etc/tdnf/tdnf.conf 37 | #tdnf_conf= 38 | -------------------------------------------------------------------------------- /etc/tdnf/pluginconf.d/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | install(FILES "tdnfrepogpgcheck.conf" "tdnfmetalink.conf" 10 | DESTINATION "${SYSCONFDIR}/tdnf/pluginconf.d" 11 | COMPONENT etc 12 | ) 13 | -------------------------------------------------------------------------------- /etc/tdnf/pluginconf.d/tdnfmetalink.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | -------------------------------------------------------------------------------- /etc/tdnf/pluginconf.d/tdnfrepogpgcheck.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | -------------------------------------------------------------------------------- /etc/tdnf/tdnf.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | gpgcheck=1 3 | installonly_limit=3 4 | clean_requirements_on_remove=0 5 | repodir=/etc/yum.repos.d 6 | cachedir=/var/cache/tdnf 7 | -------------------------------------------------------------------------------- /history/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | set(TDNF_HISTORY_UTIL_BIN tdnf-history-util) 10 | 11 | configure_file( 12 | config.h.in 13 | ${CMAKE_CURRENT_SOURCE_DIR}/config.h 14 | ) 15 | 16 | add_executable(${TDNF_HISTORY_UTIL_BIN} 17 | main.c 18 | ) 19 | 20 | add_library(${LIB_TDNF_HISTORY} STATIC 21 | history.c 22 | ) 23 | 24 | install(TARGETS ${TDNF_HISTORY_UTIL_BIN} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/tdnf COMPONENT binary) 25 | 26 | target_link_libraries(${TDNF_HISTORY_UTIL_BIN} 27 | ${RPM_LIBRARIES} 28 | ${SQLITE3_LIBRARIES} 29 | ${LIB_TDNF_HISTORY} 30 | ) 31 | 32 | target_link_libraries(${LIB_TDNF_HISTORY} 33 | ${RPM_LIBRARIES} 34 | ${SQLITE3_LIBRARIES} 35 | ) 36 | -------------------------------------------------------------------------------- /history/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define HISTORY_DB_FILE "history.db" 4 | 5 | #cmakedefine HISTORY_DB_DIR "@HISTORY_DB_DIR@" 6 | -------------------------------------------------------------------------------- /history/history.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "config.h" 15 | 16 | #define HISTORY_TRANS_TYPE_BASE 0 17 | #define HISTORY_TRANS_TYPE_DELTA 1 18 | 19 | #define HISTORY_ITEM_TYPE_SET 0 20 | #define HISTORY_ITEM_TYPE_ADD 1 21 | #define HISTORY_ITEM_TYPE_REMOVE 2 22 | 23 | struct history_ctx 24 | { 25 | sqlite3 *db; 26 | int *installed_ids; /* installed ids must be sorted */ 27 | int installed_count; 28 | char *cookie; 29 | int trans_id; 30 | }; 31 | 32 | struct history_delta 33 | { 34 | int *added_ids; 35 | int added_count; 36 | int *removed_ids; 37 | int removed_count; 38 | }; 39 | 40 | struct history_flags_delta 41 | { 42 | int *changed_ids; 43 | int *values; 44 | int count; 45 | }; 46 | 47 | struct history_transaction 48 | { 49 | int id; 50 | int type; 51 | char *cmdline; 52 | time_t timestamp; 53 | char *cookie; 54 | struct history_delta delta; 55 | struct history_flags_delta flags_delta; 56 | }; 57 | 58 | struct history_nevra_map 59 | { 60 | int count; 61 | char **idmap; 62 | }; 63 | 64 | struct history_ctx *create_history_ctx(const char *db_filename); 65 | void destroy_history_ctx(struct history_ctx *ctx); 66 | 67 | int history_sync(struct history_ctx *ctx, rpmts ts); 68 | 69 | char *history_nevra_from_id(struct history_ctx *ctx, int id); 70 | struct history_nevra_map *history_nevra_map(struct history_ctx *ctx); 71 | void history_free_nevra_map(struct history_nevra_map *); 72 | char *history_get_nevra(struct history_nevra_map *hnm, int id); 73 | 74 | void history_free_delta(struct history_delta *hd); 75 | struct history_delta *history_get_delta(struct history_ctx *ctx, int trans_id); 76 | struct history_delta *history_get_delta_range(struct history_ctx *ctx, int trans_id0, int trans_id1); 77 | 78 | int history_add_transaction(struct history_ctx *ctx, const char *cmdline); 79 | int history_record_state(struct history_ctx *ctx); 80 | int history_update_state(struct history_ctx *ctx, rpmts ts, const char *cmdline); 81 | 82 | int history_get_transactions(struct history_ctx *ctx, 83 | struct history_transaction **ptas, 84 | int *pcount, 85 | int reverse, int from, int to); 86 | void history_free_transactions(struct history_transaction *tas, int count); 87 | 88 | int history_set_auto_flag(struct history_ctx *ctx, const char *name, int value); 89 | int history_get_auto_flag(struct history_ctx *ctx, const char *name, int *pvalue); 90 | 91 | int history_restore_auto_flags(struct history_ctx *ctx, int trans_id); 92 | int history_replay_auto_flags(struct history_ctx *ctx, int from, int to); 93 | 94 | void history_free_flags_delta(struct history_flags_delta * hfd); 95 | struct history_flags_delta * 96 | history_get_flags_delta(struct history_ctx *ctx, int from, int to); 97 | 98 | -------------------------------------------------------------------------------- /include/tdnfclierror.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __TDNF_CLI_ERR_H__ 10 | #define __TDNF_CLI_ERR_H__ 11 | 12 | #define ERROR_TDNF_CLI_CHECK_UPDATES_AVAILABLE 100 13 | #define ERROR_TDNF_CLI_BASE 900 14 | #define ERROR_TDNF_CLI_NO_MATCH (ERROR_TDNF_CLI_BASE + 1) 15 | #define ERROR_TDNF_CLI_INVALID_ARGUMENT (ERROR_TDNF_CLI_BASE + 2) 16 | #define ERROR_TDNF_CLI_CLEAN_REQUIRES_OPTION (ERROR_TDNF_CLI_BASE + 3) 17 | #define ERROR_TDNF_CLI_NOT_ENOUGH_ARGS (ERROR_TDNF_CLI_BASE + 4) 18 | #define ERROR_TDNF_CLI_NOTHING_TO_DO (ERROR_TDNF_CLI_BASE + 5) 19 | #define ERROR_TDNF_CLI_CHECKLOCAL_EXPECT_DIR (ERROR_TDNF_CLI_BASE + 6) 20 | #define ERROR_TDNF_CLI_PROVIDES_EXPECT_ARG (ERROR_TDNF_CLI_BASE + 7) 21 | #define ERROR_TDNF_CLI_OPTION_NAME_INVALID (ERROR_TDNF_CLI_BASE + 8) 22 | #define ERROR_TDNF_CLI_OPTION_ARG_REQUIRED (ERROR_TDNF_CLI_BASE + 9) 23 | #define ERROR_TDNF_CLI_OPTION_ARG_UNEXPECTED (ERROR_TDNF_CLI_BASE + 10) 24 | #define ERROR_TDNF_CLI_SETOPT_NO_EQUALS (ERROR_TDNF_CLI_BASE + 11) 25 | #define ERROR_TDNF_CLI_NO_SUCH_CMD (ERROR_TDNF_CLI_BASE + 12) 26 | #define ERROR_TDNF_CLI_DOWNLOADDIR_REQUIRES_DOWNLOADONLY (ERROR_TDNF_CLI_BASE + 13) 27 | #define ERROR_TDNF_CLI_ONE_DEP_ONLY (ERROR_TDNF_CLI_BASE + 14) 28 | #define ERROR_TDNF_CLI_ALLDEPS_REQUIRES_DOWNLOADONLY (ERROR_TDNF_CLI_BASE + 15) 29 | #define ERROR_TDNF_CLI_NODEPS_REQUIRES_DOWNLOADONLY (ERROR_TDNF_CLI_BASE + 16) 30 | #define ERROR_TDNF_CLI_INVALID_MIXED_QUERY_QUERYFORMAT (ERROR_TDNF_CLI_BASE + 17) 31 | 32 | #endif /* __TDNF_CLI_ERR_H__ */ 33 | -------------------------------------------------------------------------------- /include/tdnfplugineventmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef _TDNF_PLUGIN_EVENT_MAP_H_ 10 | #define _TDNF_PLUGIN_EVENT_MAP_H_ 11 | 12 | #include "tdnfplugin.h" 13 | 14 | #define TDNF_PLUGIN_EVENT_MAP_VERSION "1.0.0" 15 | 16 | /* 17 | * get current plugin event map version. event maps 18 | * might add to existing definition or add new. 19 | * please see map below. Changes will be backward 20 | * compatible unless mentioned otherwise. So it 21 | * is enough to ensure >= a known good version. 22 | */ 23 | const char * 24 | TDNFPluginGetEventMapVersion( 25 | ); 26 | 27 | #define TDNF_EVENT_ITEM_TDNF_HANDLE "tdnf.handle" 28 | #define TDNF_EVENT_ITEM_REPO_SECTION "repo.section" 29 | #define TDNF_EVENT_ITEM_REPO_ID "repo.id" 30 | #define TDNF_EVENT_ITEM_REPO_DATADIR "repo.datadir" 31 | #define TDNF_EVENT_ITEM_REPO_MD_URL "repomd.url" 32 | #define TDNF_EVENT_ITEM_REPO_MD_FILE "repomd.file" 33 | 34 | typedef enum 35 | { 36 | TDNF_EVENT_ITEM_TYPE_NONE, 37 | TDNF_EVENT_ITEM_TYPE_INT, 38 | TDNF_EVENT_ITEM_TYPE_STRING, 39 | TDNF_EVENT_ITEM_TYPE_PTR 40 | }TDNF_EVENT_ITEM_TYPE; 41 | 42 | typedef struct _TDNF_PLUGIN_EVENT_ITEM_ 43 | { 44 | TDNF_EVENT_ITEM_TYPE nType; 45 | const char *pcszName; 46 | }TDNF_PLUGIN_EVENT_ITEM, *PTDNF_PLUGIN_EVENT_ITEM; 47 | 48 | typedef struct _TDNF_PLUGIN_EVENT_MAP_ 49 | { 50 | int nItems; 51 | TDNF_PLUGIN_EVENT nEvent; 52 | PTDNF_PLUGIN_EVENT_ITEM pItems; 53 | }TDNF_PLUGIN_EVENT_MAP, *PTDNF_PLUGIN_EVENT_MAP; 54 | 55 | #define TDNF_PLUGIN_EVENT_MAPS \ 56 | { \ 57 | {\ 58 | 1,\ 59 | MAKE_PLUGIN_EVENT(TDNF_PLUGIN_EVENT_TYPE_INIT, 0, 0),\ 60 | {\ 61 | {TDNF_EVENT_ITEM_TYPE_PTR, TDNF_EVENT_ITEM_TDNF_HANDLE}\ 62 | }\ 63 | }, \ 64 | {\ 65 | 1,\ 66 | MAKE_PLUGIN_EVENT(TDNF_PLUGIN_EVENT_TYPE_REPO,\ 67 | TDNF_PLUGIN_EVENT_STATE_READCONFIG,\ 68 | TDNF_PLUGIN_EVENT_PHASE_START),\ 69 | {\ 70 | {TDNF_EVENT_ITEM_TYPE_PTR, TDNF_EVENT_ITEM_REPO_SECTION}\ 71 | }\ 72 | },\ 73 | {\ 74 | 3,\ 75 | MAKE_PLUGIN_EVENT(TDNF_PLUGIN_EVENT_TYPE_REPO_MD,\ 76 | TDNF_PLUGIN_EVENT_STATE_DOWNLOAD,\ 77 | TDNF_PLUGIN_EVENT_PHASE_END),\ 78 | {\ 79 | {TDNF_EVENT_ITEM_TYPE_STRING, TDNF_EVENT_ITEM_REPO_ID},\ 80 | {TDNF_EVENT_ITEM_TYPE_STRING, TDNF_EVENT_ITEM_REPO_DATADIR},\ 81 | {TDNF_EVENT_ITEM_TYPE_STRING, TDNF_EVENT_ITEM_REPO_BASEURL},\ 82 | {TDNF_EVENT_ITEM_TYPE_STRING, TDNF_EVENT_ITEM_REPO_MD_FILE}\ 83 | }\ 84 | }\ 85 | }; 86 | 87 | #endif /* _TDNF_PLUGIN_EVENT_MAP_H_ */ 88 | -------------------------------------------------------------------------------- /jsondump/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | set(TDNF_JSON_BIN jsondumptest) 10 | 11 | add_executable(${TDNF_JSON_BIN} 12 | test.c 13 | ) 14 | 15 | install(TARGETS ${TDNF_JSON_BIN} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT binary) 16 | 17 | add_library(${LIB_TDNF_JSONDUMP} STATIC 18 | jsondump.c 19 | ) 20 | 21 | target_link_libraries(${TDNF_JSON_BIN} 22 | ${LIB_TDNF_JSONDUMP} 23 | ) 24 | -------------------------------------------------------------------------------- /jsondump/jsondump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | #include 11 | 12 | struct json_dump{ 13 | char *buf; 14 | unsigned int buf_size; 15 | unsigned int pos; 16 | }; 17 | 18 | struct json_dump *jd_create(unsigned int size); 19 | void jd_destroy(struct json_dump *jd); 20 | 21 | int jd_map_start(struct json_dump *jd); 22 | int jd_map_add_string(struct json_dump *jd, const char *key, const char *value); 23 | int jd_map_add_int(struct json_dump *jd, const char *key, int value); 24 | int jd_map_add_int64(struct json_dump *jd, const char *key, int64_t value); 25 | int jd_map_add_bool(struct json_dump *jd, const char *key, int value); 26 | int jd_map_add_null(struct json_dump *jd, const char *key); 27 | int jd_map_add_fmt(struct json_dump *jd, const char *key, const char *format, ...); 28 | int jd_map_add_child(struct json_dump *jd, const char *key, const struct json_dump *jd_child); 29 | 30 | int jd_list_start(struct json_dump *jd); 31 | int jd_list_add_string(struct json_dump *jd, const char *value); 32 | int jd_list_add_int(struct json_dump *jd, int value); 33 | int jd_list_add_int64(struct json_dump *jd, int64_t value); 34 | int jd_list_add_bool(struct json_dump *jd, int value); 35 | int jd_list_add_null(struct json_dump *jd); 36 | int jd_list_add_fmt(struct json_dump *jd, const char *format, ...); 37 | int jd_list_add_child(struct json_dump *jd, const struct json_dump *jd_child); 38 | -------------------------------------------------------------------------------- /jsondump/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include 10 | 11 | #include "jsondump.h" 12 | 13 | #define CHECK_RC(x) if (x) {fprintf(stderr, "FAIL: rc != 0 in line %d\n", __LINE__); } 14 | #define CHECK_NULL(x) if (x == NULL) {fprintf(stderr, "FAIL: NULL returned in line %d\n", __LINE__); } 15 | 16 | int main(void) 17 | { 18 | struct json_dump *jd, *jd1; 19 | 20 | /* flat map with all inds of values */ 21 | jd = jd_create(0); 22 | CHECK_NULL(jd); 23 | 24 | CHECK_RC(jd_map_start(jd)); 25 | CHECK_RC(jd_map_add_string(jd, "foo", "bar")); 26 | CHECK_RC(jd_map_add_string(jd, "goo", "car")); 27 | CHECK_RC(jd_map_add_string(jd, "hoo", "\tdar\n")); 28 | CHECK_RC(jd_map_add_fmt(jd, "ioo", "%d ears", 2)); 29 | CHECK_RC(jd_map_add_null(jd, "nothing")); 30 | CHECK_RC(jd_map_add_bool(jd, "yes", 1)); 31 | CHECK_RC(jd_map_add_bool(jd, "no", 0)); 32 | 33 | printf("%s\n", jd->buf); 34 | 35 | /* nested map in map */ 36 | jd1 = jd_create(0); 37 | CHECK_NULL(jd1); 38 | 39 | CHECK_RC(jd_map_start(jd1)); 40 | CHECK_RC(jd_map_add_child(jd1, "nested", jd)); 41 | 42 | printf("%s\n", jd1->buf); 43 | 44 | jd_destroy(jd); 45 | jd_destroy(jd1); 46 | 47 | /* list with strings */ 48 | jd = jd_create(0); 49 | CHECK_NULL(jd); 50 | 51 | CHECK_RC(jd_list_start(jd)); 52 | for(int i = 0; i < 10; i++) { 53 | char buf[3]; 54 | snprintf(buf, sizeof(buf), "%d", i); 55 | jd_list_add_string(jd, buf); 56 | } 57 | jd_list_add_null(jd); 58 | 59 | printf("%s\n", jd->buf); 60 | 61 | jd_destroy(jd); 62 | 63 | /* list with format strings */ 64 | jd = jd_create(0); 65 | CHECK_NULL(jd); 66 | 67 | CHECK_RC(jd_list_start(jd)); 68 | for(int i = 0; i < 10; i++) { 69 | CHECK_RC(jd_list_add_fmt(jd, "i=%d", i)); 70 | } 71 | 72 | printf("%s\n", jd->buf); 73 | 74 | jd_destroy(jd); 75 | 76 | /* list of ints */ 77 | jd = jd_create(0); 78 | CHECK_NULL(jd); 79 | 80 | CHECK_RC(jd_list_start(jd)); 81 | for(int i = 0; i < 10; i++) { 82 | CHECK_RC(jd_list_add_int(jd, i)); 83 | } 84 | 85 | printf("%s\n", jd->buf); 86 | 87 | jd_destroy(jd); 88 | 89 | /* list of bools */ 90 | jd = jd_create(0); 91 | CHECK_NULL(jd); 92 | 93 | CHECK_RC(jd_list_start(jd)); 94 | CHECK_RC(jd_list_add_bool(jd, 1)); 95 | CHECK_RC(jd_list_add_bool(jd, 0)); 96 | 97 | printf("%s\n", jd->buf); 98 | 99 | jd_destroy(jd); 100 | 101 | return 0; 102 | } -------------------------------------------------------------------------------- /llconf/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | add_library(${LIB_TDNF_LLCONF} STATIC 10 | entry.c 11 | ini.c 12 | lines.c 13 | modules.c 14 | nodes.c 15 | strutils.c 16 | ) 17 | 18 | -------------------------------------------------------------------------------- /llconf/entry.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #pragma once 23 | 24 | /** 25 | * A structure to hold the results of #cnf_find_entry. 26 | */ 27 | struct cnfresult{ 28 | struct cnfresult *next; /**< The next result in the result set. */ 29 | char *path; /**< The full path to the matched entry in the configuration tree. */ 30 | struct cnfnode *cnfnode; /**< A reference to the node in the configuration tree. */ 31 | }; 32 | 33 | /* internal use: */ 34 | struct cnfresult *create_cnfresult(struct cnfnode *cn, const char *path); 35 | void destroy_cnfresult(struct cnfresult *cr); 36 | void destroy_cnfresult_list(struct cnfresult *cr_list); 37 | 38 | /* public use: */ 39 | struct cnfresult *cnf_find_entry(struct cnfnode *cn_root, const char *path); 40 | struct cnfnode *cnf_add_branch(struct cnfnode *cn_root, const char *path, int do_merge); 41 | int cnf_del_branch(struct cnfnode *cn_root, const char *path, int del_empty); 42 | int cnf_set_entry(struct cnfnode *cn_root, const char *path, const char *val, int do_create); 43 | const char *cnf_get_entry(struct cnfnode *cn_root, const char *path); 44 | struct cnfnode *cnf_get_node(struct cnfnode *cn_root, const char *path); 45 | 46 | void strip_cnftree(struct cnfnode *cn_root); 47 | -------------------------------------------------------------------------------- /llconf/ini.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #pragma once 23 | 24 | struct cnfnode *parse_ini(struct cnfmodule *cm, FILE *fptr); 25 | int unparse_ini(struct cnfmodule *cm, FILE *fptr, struct cnfnode *cn_root); 26 | void register_ini(struct cnfnode *opt_root); 27 | struct cnfmodule *clone_cnfmodule_ini(struct cnfnode *opt_root); 28 | -------------------------------------------------------------------------------- /llconf/lines.c: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "lines.h" 27 | 28 | struct confline *create_confline(const char *line) 29 | { 30 | struct confline *cl = NULL; 31 | 32 | cl = malloc(sizeof(struct confline)); 33 | if(cl){ 34 | memset(cl, 0, sizeof(struct confline)); 35 | cl->line = strdup(line); 36 | } 37 | return cl; 38 | } 39 | 40 | void destroy_confline(struct confline *cl) 41 | { 42 | if(cl){ 43 | if(cl->line) free(cl->line); 44 | free(cl); 45 | } 46 | } 47 | 48 | void destroy_confline_list(struct confline *cl_list) 49 | { 50 | struct confline *cl, *cl_next; 51 | 52 | for(cl = cl_list; cl; cl = cl_next){ 53 | cl_next = cl->next; 54 | destroy_confline(cl); 55 | } 56 | } 57 | 58 | struct confline *append_confline(struct confline *cl_list, struct confline *cl) 59 | { 60 | if(cl_list){ 61 | struct confline **pcl; 62 | for(pcl = &(cl_list->next); *pcl; pcl = &((*pcl)->next)); 63 | *pcl = cl; 64 | return cl_list; 65 | }else 66 | return cl; 67 | } 68 | 69 | struct confline *read_conflines(FILE *fptr) 70 | { 71 | char line[MAX_CONFLINE]; 72 | struct confline *cl = NULL, *cl_next, *cl_root = NULL; 73 | 74 | while(fgets(line, MAX_CONFLINE-1, fptr)){ 75 | cl_next = create_confline(line); 76 | if(cl) 77 | cl->next = cl_next; 78 | else 79 | cl_root = cl_next; 80 | cl = cl_next; 81 | } 82 | return cl_root; 83 | } 84 | -------------------------------------------------------------------------------- /llconf/lines.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #pragma once 23 | 24 | /** \file 25 | * Handling for collections of lines of text. 26 | * 27 | * The #confline structure provides for storage of a list of lines of text. 28 | */ 29 | 30 | /** The maximum length of the text content of a #confline node. */ 31 | #define MAX_CONFLINE 1024 32 | 33 | /** A linked list representing the lines of text from a configuration file. */ 34 | struct confline 35 | { 36 | struct confline *next; /**< The next entry in the list, or NULL for the end of the list. */ 37 | char *line; /**< The NUL-terminated line of text. */ 38 | }; 39 | 40 | /** Create a #confline representing the given line of text. 41 | * @param [in] line The line of text. 42 | * @return A new #confline containing a copy of the given text. 43 | */ 44 | struct confline *create_confline(const char *line); 45 | 46 | /** Destroy a #confline and its copy of the contained text. 47 | * @param [in] cl The #confline to free. 48 | */ 49 | void destroy_confline(struct confline *cl); 50 | 51 | /** Destroy a list of #confline nodes. 52 | * #destroy_confline will be called on each node in the list. 53 | * @param [in] cl_list The head of the list of #confline entries to free. 54 | */ 55 | void destroy_confline_list(struct confline *cl_list); 56 | 57 | /** Read the contents of a stream into a #confline list. 58 | * @param [in] fptr The stream to read. 59 | * @return The head of the #confline list representing all of the lines of 60 | * the file. 61 | */ 62 | struct confline *read_conflines(FILE *fptr); 63 | 64 | /** Append a #confline to an existing #confline list. 65 | * @param [in] cl_list The existing list to which the given line is to be 66 | * appended. May be NULL if creating a new list. 67 | * @param [in] cl The #confline to append. 68 | * @return The new head of the #confline list. This will be the same as 69 | * cl_list unless cl_list is NULL, in which case cl becomes the head 70 | * of a new list. 71 | */ 72 | struct confline *append_confline(struct confline *cl_list, struct confline *cl); 73 | 74 | -------------------------------------------------------------------------------- /llconf/modules.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #pragma once 23 | 24 | extern struct cnfmodule *cnfmodules; 25 | 26 | /** Information for registering a parser module. */ 27 | struct cnfmodule 28 | { 29 | struct cnfmodule *next; /**< The next module in the registration list. */ 30 | char *name; /**< The text name of this parser module. */ 31 | char *default_file; /**< The file that this module operates on, if none is specified when the parser is instantiated. */ 32 | struct cnfnode *(*parser)(struct cnfmodule *cm, FILE *fptr); /**< The function to use to create an in-memory tree from the given stream. */ 33 | int (*unparser)(struct cnfmodule *cm, FILE *fptr, struct cnfnode *cn_root); /**< The function to use to write the in-memory tree to the given stream. */ 34 | struct cnfnode *opt_root; /**< The default set of options for this parser. */ 35 | }; 36 | 37 | void register_cnfmodule(struct cnfmodule *cm, struct cnfnode *opt_root); 38 | 39 | void unregister_all(void); 40 | 41 | struct cnfmodule *find_cnfmodule(const char *name); 42 | 43 | void cnfmodule_setopts(struct cnfmodule *cm, struct cnfnode *opt_root); 44 | 45 | struct cnfnode *parse_options(const char *string); 46 | 47 | struct cnfnode *cnfmodule_parse(struct cnfmodule *cm, FILE *fin); 48 | 49 | struct cnfnode *cnfmodule_parse_file(struct cnfmodule *cm, const char *fname); 50 | 51 | void destroy_cnfmodule(struct cnfmodule *cm); 52 | 53 | struct cnfmodule *clone_cnfmodule(struct cnfmodule *cm, 54 | const char *new_name, 55 | const char *default_file, 56 | struct cnfnode *opt_root); 57 | 58 | int cnfmodule_unparse(struct cnfmodule *cm, FILE* fout, 59 | struct cnfnode *cn_root); 60 | 61 | int cnfmodule_unparse_file(struct cnfmodule *cm, const char *fname, 62 | struct cnfnode *cn_root); 63 | 64 | int cnfmodule_register_plugin(const char *name, const char *path, struct cnfnode *opt_root); 65 | -------------------------------------------------------------------------------- /llconf/nodes.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef __LLCONF_NODES_H_INCLUDED 23 | #define __LLCONF_NODES_H_INCLUDED 24 | 25 | /** A node in a parsed configuration tree. */ 26 | struct cnfnode{ 27 | struct cnfnode *next; /**< The next sibling of this node. */ 28 | char *name; /**< The name of this node; may be NULL. */ 29 | char *value; /**< The value at this leaf node; usually NULL for non-leaf nodes, but not necessarily. */ 30 | struct cnfnode *first_child; /**< The first child underneath this node. */ 31 | struct cnfnode *parent; /**< The parent node of this node. */ 32 | }; 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | struct cnfnode *create_cnfnode(const char *name); 39 | 40 | struct cnfnode *clone_cnfnode(const struct cnfnode *cn); 41 | struct cnfnode *clone_cnftree(const struct cnfnode *cn_root); 42 | 43 | const char *cnfnode_getval(const struct cnfnode *cn); 44 | 45 | const char *cnfnode_getname(const struct cnfnode *cn); 46 | 47 | void cnfnode_setval(struct cnfnode *cn, const char *value); 48 | void cnfnode_setname(struct cnfnode *cn, const char *name); 49 | 50 | /* free memory of node, leaving children intact */ 51 | void destroy_cnfnode(struct cnfnode *cn); 52 | 53 | /* free recursively all children, then cn */ 54 | void destroy_cnftree(struct cnfnode *cn); 55 | 56 | /* append a node */ 57 | void append_node(struct cnfnode *cn_parent, struct cnfnode *cn); 58 | 59 | /* insert a node */ 60 | void insert_node_before(struct cnfnode *cn_before, struct cnfnode *cn); 61 | 62 | /* remove a node from tree list (but do not destroy it) */ 63 | void unlink_node(struct cnfnode *cn); 64 | 65 | /* walks through list starting with cnf_list, 66 | and returns 1st node with matching name */ 67 | struct cnfnode *find_node(struct cnfnode *cn_list, const char *name); 68 | 69 | #define find_child(cn_parent, name) find_node(cn_parent->first_child, name) 70 | 71 | int compare_cnfnode(const struct cnfnode *cn1, const struct cnfnode *cn2); 72 | int compare_cnftree(const struct cnfnode *cn_root1, const struct cnfnode *cn_root2); 73 | int compare_cnftree_children(const struct cnfnode *cn_root1, const struct cnfnode *cn_root2); 74 | 75 | void dump_nodes(struct cnfnode *cn_root, int level); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif // __LLCONF_NODES_H_INCLUDED 82 | -------------------------------------------------------------------------------- /llconf/strutils.h: -------------------------------------------------------------------------------- 1 | /* -*- linux-c -*- */ 2 | /* 3 | This file is part of llconf2 4 | 5 | Copyright (C) 2004-2007 Oliver Kurth 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #pragma once 23 | 24 | #define cp_buf_until(dest, p, expr) \ 25 | { \ 26 | char *q = buf; \ 27 | while(*p && (q < dest+sizeof(dest)-1) && (expr)) *q++ = *p++; \ 28 | *q = 0; \ 29 | } 30 | 31 | char *dup_next_word(const char **pp); 32 | char *dup_next_word_b(const char **pp, char *buf, int n); 33 | char *dup_next_quoted(const char **pp, char qchar); 34 | char *dup_next_quoted_b(const char **pp, char *buf, int n, char qchar); 35 | char *dup_next_line(const char **pp); 36 | char *dup_next_line_b(const char **pp, char *buf, int n); 37 | char *dup_line_until(const char **pp, char until); 38 | char *dup_line_until_b(const char **pp, char until, char *buf, int n); 39 | 40 | char *dup_quote_string(const char *string, char qchar); 41 | char *dup_unquote_string(const char *qstring, char qchar); 42 | char *dup_unquote_string_ifquoted(const char *qstring, char qchar); 43 | 44 | /* these functions copy from *pp to *pq, but do not null terminate, 45 | and advance the pointers */ 46 | void cp_spaces(const char **pp, char **pq, int n); 47 | void cp_word(const char **pp, char **pq, int n); 48 | void cp_quoted(const char **pp, char **pq, int n); 49 | void cp_quoted_ifquoted(const char **pp, char **pq, int n, char qchar); 50 | 51 | /* these functions advance the pointer *pp */ 52 | void skip_spaces(const char **pp); 53 | void skip_word(const char **pp); 54 | void skip_quoted(const char **pp); 55 | void skip_quoted_ifquoted(const char **pp, char qchar); 56 | 57 | char *strjoin(const char *s1, const char *s2); 58 | 59 | /* FIXME(if bored): use cp_ and skip_ functions in the dup_ functions to reduce code... */ 60 | -------------------------------------------------------------------------------- /plugins/.gitignore: -------------------------------------------------------------------------------- 1 | config.h 2 | -------------------------------------------------------------------------------- /plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | add_subdirectory("repogpgcheck") 10 | add_subdirectory("metalink") 11 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # tdnf plugins 2 | 3 | plugins are a way to extend tdnf functionality. 4 | 5 | tdnf plugins follow the same config and command line conventions as yum. 6 | 7 | ## enable plugins 8 | tdnf will install with plugins deactivated by default. This is because the primary switch 9 | to turn on plugins is in tdnf conf file (/etc/tdnf/tdnf.conf by default). 10 | To enable plugins, the config file should have 11 | 12 | ```plugins=1``` 13 | 14 | ## plugin discovery 15 | tdnf will look in ```/etc/tdnf/pluginconf.d``` by default for plugin configurations. 16 | For all config files with ```enabled=1``` set, tdnf will look for a corresponding 17 | shared library in ```/tdnf-plugins//lib.so```. 18 | ```pluginpath``` and ```pluginconfpath``` are config settings to change default paths. 19 | 20 | ## overriding plugin load 21 | tdnf allows command line overrides with ```--enableplugin=``` to enable a plugin 22 | that is deactivated in the corresponding plugin config file. 23 | Similarly, ```--disableplugin=``` can be used to deactivate a plugin which is 24 | otherwise enabled in it's corresponding config file. 25 | 26 | For eg: ```tdnf --disableplugin=* --enableplugin=myplugin``` will deactivate all plugins 27 | but ```myplugin``` that is subsequently enabled. The deactivate and enable overrides are 28 | sequential, cumulative and support globs. 29 | Therefore, it does matter where you place the deactivate option. 30 | -------------------------------------------------------------------------------- /plugins/metalink/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | project(tdnfmetalink VERSION 1.0.0 LANGUAGES C) 10 | 11 | include_directories(${CMAKE_SOURCE_DIR}/include) 12 | 13 | #make config.h with 14 | #PACKAGE_NAME and PACKAGE_VERSION defined 15 | configure_file( 16 | config.h.in 17 | ${CMAKE_CURRENT_SOURCE_DIR}/config.h @ONLY 18 | ) 19 | 20 | add_library(${PROJECT_NAME} SHARED 21 | api.c 22 | metalink.c 23 | utils.c 24 | list.c 25 | ) 26 | 27 | target_link_libraries(${PROJECT_NAME} 28 | ${EXPAT_LIBRARIES} 29 | ${LIB_TDNF} 30 | ) 31 | 32 | set_target_properties(${PROJECT_NAME} PROPERTIES 33 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/lib) 34 | install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/tdnf-plugins) 35 | -------------------------------------------------------------------------------- /plugins/metalink/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PLUGIN_NAME "@PROJECT_NAME@" 4 | #define PLUGIN_VERSION "@PROJECT_VERSION@" 5 | -------------------------------------------------------------------------------- /plugins/metalink/defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __PLUGINS_METALINK_DEFINES_H 10 | #define __PLUGINS_METALINK_DEFINES_H 11 | 12 | 13 | #define ERROR_TDNF_METALINK_START 2700 14 | #define ERROR_TDNF_METALINK_PARSER_INVALID_DOC_OBJECT ERROR_TDNF_METALINK_START + 1 15 | #define ERROR_TDNF_METALINK_PARSER_INVALID_ROOT_ELEMENT ERROR_TDNF_METALINK_START + 2 16 | #define ERROR_TDNF_METALINK_PARSER_MISSING_FILE_ATTR ERROR_TDNF_METALINK_START + 3 17 | #define ERROR_TDNF_METALINK_PARSER_INVALID_FILE_NAME ERROR_TDNF_METALINK_START + 4 18 | #define ERROR_TDNF_METALINK_PARSER_MISSING_FILE_SIZE ERROR_TDNF_METALINK_START + 5 19 | #define ERROR_TDNF_METALINK_PARSER_MISSING_HASH_ATTR ERROR_TDNF_METALINK_START + 6 20 | #define ERROR_TDNF_METALINK_PARSER_MISSING_HASH_CONTENT ERROR_TDNF_METALINK_START + 7 21 | #define ERROR_TDNF_METALINK_PARSER_MISSING_URL_ATTR ERROR_TDNF_METALINK_START + 8 22 | #define ERROR_TDNF_METALINK_PARSER_MISSING_URL_CONTENT ERROR_TDNF_METALINK_START + 9 23 | #define ERROR_TDNF_METALINK_END ERROR_TDNF_METALINK_START + 10 24 | 25 | #define TDNF_REPO_CONFIG_METALINK_KEY "metalink" 26 | 27 | #define METALINK_PLUGIN_ERROR "metalink plugin error" 28 | #define METALINK_ERROR_TABLE \ 29 | { \ 30 | {ERROR_TDNF_METALINK_PARSER_INVALID_DOC_OBJECT, "ERROR_TDNF_METALINK_PARSER_INVALID_DOC_OBJECT", "Failed to parse and create document tree"},\ 31 | {ERROR_TDNF_METALINK_PARSER_INVALID_ROOT_ELEMENT, "ERROR_TDNF_METALINK_PARSER_INVALID_ROOT_ELEMENT", "Root element not found"},\ 32 | {ERROR_TDNF_METALINK_PARSER_MISSING_FILE_ATTR, "ERROR_TDNF_METALINK_PARSER_MISSING_FILE_ATTR", "Missing filename in metalink file"},\ 33 | {ERROR_TDNF_METALINK_PARSER_INVALID_FILE_NAME, "ERROR_TDNF_METALINK_PARSER_INVALID_FILE_NAME", "Invalid filename present"},\ 34 | {ERROR_TDNF_METALINK_PARSER_MISSING_FILE_SIZE, "ERROR_TDNF_METALINK_PARSER_MISSING_FILE_SIZE", "Missing file size in metalink file"},\ 35 | {ERROR_TDNF_METALINK_PARSER_MISSING_HASH_ATTR, "ERROR_TDNF_METALINK_PARSER_MISSING_HASH_ATTR", "Missing attribute in hash tag"},\ 36 | {ERROR_TDNF_METALINK_PARSER_MISSING_HASH_CONTENT, "ERROR_TDNF_METALINK_PARSER_MISSING_HASH_CONTENT", "Missing content in hash tag value"},\ 37 | {ERROR_TDNF_METALINK_PARSER_MISSING_URL_ATTR, "ERROR_TDNF_METALINK_PARSER_MISSING_URL_ATTR", "Missing attribute in url tag"},\ 38 | {ERROR_TDNF_METALINK_PARSER_MISSING_HASH_CONTENT, "ERROR_TDNF_METALINK_PARSER_MISSING_URL_CONTENT", "Missing content in url tag value"},\ 39 | }; 40 | #endif /* __PLUGINS_METALINK_DEFINES_H__ */ 41 | -------------------------------------------------------------------------------- /plugins/metalink/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __PLUGINS_METALINK_INCLUDES_H__ 10 | #define __PLUGINS_METALINK_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | //libcurl 28 | #include 29 | 30 | #include "../../common/defines.h" 31 | #include "../../common/structs.h" 32 | #include "../../common/prototypes.h" 33 | #include "../../client/includes.h" 34 | #include "defines.h" 35 | #include "structs.h" 36 | #include "prototypes.h" 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /plugins/metalink/structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | //Metalink Structures. 12 | typedef struct _TDNF_ML_LIST_ 13 | { 14 | struct _TDNF_ML_LIST_ *next; 15 | void* data; 16 | } TDNF_ML_LIST, TDNF_ML_URL_LIST, TDNF_ML_HASH_LIST; 17 | 18 | //Metalink hash info per hash type. 19 | typedef struct _TDNF_ML_HASH_INFO_ 20 | { 21 | char *type; 22 | char *value; 23 | } TDNF_ML_HASH_INFO; 24 | 25 | //Metalink url info per hash type. 26 | typedef struct _TDNF_ML_URL_INFO_ 27 | { 28 | char *protocol; 29 | char *type; 30 | char *location; 31 | char *url; 32 | int preference; 33 | } TDNF_ML_URL_INFO; 34 | 35 | //Metalink global parsed info. 36 | typedef struct _TDNF_ML_CTX_ 37 | { 38 | char *filename; 39 | signed long timestamp; 40 | signed long size; 41 | TDNF_ML_LIST *hashes; 42 | TDNF_ML_LIST *urls; 43 | } TDNF_ML_CTX; 44 | 45 | /* per repo */ 46 | typedef struct _TDNF_METALINK_DATA_ 47 | { 48 | struct _TDNF_METALINK_DATA_ *pNext; 49 | char *pszRepoId; 50 | char *pszMetalink; 51 | TDNF_ML_CTX *ml_ctx; 52 | } TDNF_METALINK_DATA, *PTDNF_METALINK_DATA; 53 | 54 | typedef struct _TDNF_PLUGIN_HANDLE_ 55 | { 56 | PTDNF pTdnf; 57 | uint32_t nError; /* last error set by this plugin */ 58 | PTDNF_METALINK_DATA pData; 59 | } TDNF_PLUGIN_HANDLE; 60 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | project(tdnfrepogpgcheck VERSION 1.0.0 LANGUAGES C) 10 | 11 | ### External dependency: libgpgme 12 | find_package(Gpgme REQUIRED) 13 | 14 | include_directories(${CMAKE_SOURCE_DIR}/include) 15 | 16 | #make config.h with 17 | #PACKAGE_NAME and PACKAGE_VERSION defined 18 | configure_file( 19 | config.h.in 20 | ${CMAKE_CURRENT_SOURCE_DIR}/config.h @ONLY 21 | ) 22 | 23 | add_library(${PROJECT_NAME} SHARED 24 | api.c 25 | repogpgcheck.c 26 | ) 27 | 28 | target_link_libraries(${PROJECT_NAME} 29 | ${LIB_TDNF} 30 | ${GPGME_LIBRARIES} 31 | ) 32 | 33 | set_target_properties(${PROJECT_NAME} PROPERTIES 34 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/lib) 35 | install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/tdnf-plugins) 36 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PLUGIN_NAME "@PROJECT_NAME@" 4 | #define PLUGIN_VERSION "@PROJECT_VERSION@" 5 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __PLUGINS_REPOGPGCHECK_DEFINES_H__ 10 | #define __PLUGINS_REPOGPGCHECK_DEFINES_H__ 11 | 12 | #define ERROR_TDNF_GPG_BASE_START 2000 13 | #define ERROR_TDNF_GPG_ERROR ERROR_TDNF_GPG_BASE_START + 1 14 | #define ERROR_TDNF_GPG_VERSION_FAILED ERROR_TDNF_GPG_BASE_START + 2 15 | #define ERROR_TDNF_GPG_VERIFY_RESULT ERROR_TDNF_GPG_BASE_START + 3 16 | #define ERROR_TDNF_GPG_SIGNATURE_CHECK ERROR_TDNF_GPG_BASE_START + 4 17 | 18 | /* gpgme specific errors */ 19 | #define ERROR_TDNF_GPGME_START 2400 20 | 21 | #define TDNF_REPO_CONFIG_REPO_GPGCHECK_KEY "repo_gpgcheck" 22 | #define TDNF_REPO_METADATA_SIG_EXT ".asc" 23 | 24 | #define REPOGPGCHECK_PLUGIN_ERROR "repogpgcheck plugin error" 25 | #define REPOGPGCHECK_ERROR_TABLE \ 26 | { \ 27 | {ERROR_TDNF_GPG_ERROR, "ERROR_TDNF_GPG_ERROR", "unknown error"}, \ 28 | {ERROR_TDNF_GPG_VERSION_FAILED, "ERROR_TDNF_GPG_VERSION_FAILED", "version failed"}, \ 29 | {ERROR_TDNF_GPG_VERIFY_RESULT, "ERROR_TDNF_GPG_VERIFY_RESULT", "failed to verify result"}, \ 30 | {ERROR_TDNF_GPG_SIGNATURE_CHECK, "ERROR_TDNF_GPG_SIGNATURE_CHECK", "failed to verify signature"}, \ 31 | }; 32 | #endif /* __PLUGINS_REPOGPGCHECK_DEFINES_H__ */ 33 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __PLUGINS_REPOGPGCHECK_INCLUDES_H__ 10 | #define __PLUGINS_REPOGPGCHECK_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | //libcurl 26 | #include 27 | 28 | #include "../../common/defines.h" 29 | #include "../../common/structs.h" 30 | #include "../../common/prototypes.h" 31 | #include "../../client/includes.h" 32 | #include "defines.h" 33 | #include "structs.h" 34 | #include "prototypes.h" 35 | 36 | #endif /* __CLIENT_INCLUDES_H__ */ 37 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __PLUGINS_REPOGPGCHECK_PROTOTYPES_H__ 10 | #define __PLUGINS_REPOGPGCHECK_PROTOTYPES_H__ 11 | 12 | const char * 13 | TDNFPluginGetVersion( 14 | ); 15 | 16 | const char * 17 | TDNFPluginGetName( 18 | ); 19 | 20 | uint32_t 21 | TDNFPluginLoadInterface( 22 | PTDNF_PLUGIN_INTERFACE pInterface 23 | ); 24 | 25 | uint32_t 26 | TDNFRepoGPGCheckInitialize( 27 | const char *pszConfig, 28 | PTDNF_PLUGIN_HANDLE *ppHandle 29 | ); 30 | 31 | uint32_t 32 | TDNFRepoGPGCheckEventsNeeded( 33 | const PTDNF_PLUGIN_HANDLE pHandle, 34 | TDNF_PLUGIN_EVENT_TYPE *pnEvents 35 | ); 36 | 37 | uint32_t 38 | TDNFRepoGPGCheckEvent( 39 | PTDNF_PLUGIN_HANDLE pHandle, 40 | PTDNF_EVENT_CONTEXT pContext 41 | ); 42 | 43 | uint32_t 44 | TDNFRepoGPGCheckGetErrorString( 45 | PTDNF_PLUGIN_HANDLE pHandle, 46 | uint32_t nErrorCode, 47 | char **ppszError 48 | ); 49 | 50 | uint32_t 51 | TDNFRepoGPGCheckClose( 52 | PTDNF_PLUGIN_HANDLE pHandle 53 | ); 54 | 55 | void 56 | TDNFFreeRepoGPGCheckData( 57 | PTDNF_REPO_GPG_CHECK_DATA pData 58 | ); 59 | 60 | void 61 | FreePluginHandle( 62 | PTDNF_PLUGIN_HANDLE pHandle 63 | ); 64 | 65 | /* repogpgcheck.c */ 66 | uint32_t 67 | TDNFRepoGPGCheckVerifyVersion( 68 | ); 69 | 70 | uint32_t 71 | TDNFRepoMDCheckSignature( 72 | PTDNF_PLUGIN_HANDLE pHandle, 73 | PTDNF_EVENT_CONTEXT pContext 74 | ); 75 | 76 | uint32_t 77 | TDNFRepoGPGCheckReadConfig( 78 | PTDNF_PLUGIN_HANDLE pHandle, 79 | PTDNF_EVENT_CONTEXT pContext 80 | ); 81 | 82 | #endif /* __PLUGINS_REPOGPGCHECK_PROTOTYPES_H__ */ 83 | -------------------------------------------------------------------------------- /plugins/repogpgcheck/structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU Lesser General Public License v2.1 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | typedef struct _TDNF_REPO_GPG_CHECK_DATA_ 12 | { 13 | char *pszRepoId; 14 | struct _TDNF_REPO_GPG_CHECK_DATA_ *pNext; 15 | }TDNF_REPO_GPG_CHECK_DATA, *PTDNF_REPO_GPG_CHECK_DATA; 16 | 17 | typedef struct _TDNF_PLUGIN_HANDLE_ 18 | { 19 | PTDNF pTdnf; 20 | uint32_t nError; /* last error set by this plugin */ 21 | uint32_t nGPGError; /* gpg specific error. gpgerror will provide details */ 22 | PTDNF_REPO_GPG_CHECK_DATA pData; 23 | }TDNF_PLUGIN_HANDLE; 24 | -------------------------------------------------------------------------------- /pytests/.gitignore: -------------------------------------------------------------------------------- 1 | config.json 2 | virtual_disks/ 3 | mount-small-cache -------------------------------------------------------------------------------- /pytests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | include_directories(${CMAKE_SOURCE_DIR}/include) 10 | 11 | configure_file( 12 | "${CMAKE_CURRENT_SOURCE_DIR}/config.json.in" 13 | "${CMAKE_CURRENT_SOURCE_DIR}/config.json" 14 | ) 15 | 16 | configure_file( 17 | "${CMAKE_CURRENT_SOURCE_DIR}/config-install.json.in" 18 | "${CMAKE_CURRENT_SOURCE_DIR}/config-install.json" 19 | ) 20 | 21 | configure_file( 22 | "${CMAKE_CURRENT_SOURCE_DIR}/mount-small-cache.in" 23 | "${CMAKE_CURRENT_SOURCE_DIR}/mount-small-cache" @ONLY 24 | ) 25 | 26 | install(FILES config-install.json 27 | DESTINATION ${CMAKE_INSTALL_DATADIR}/tdnf/pytests 28 | RENAME config.json 29 | ) 30 | 31 | install(FILES __init__.py conftest.py 32 | DESTINATION ${CMAKE_INSTALL_DATADIR}/tdnf/pytests 33 | ) 34 | 35 | add_custom_target(check 36 | COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" pytest 37 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 38 | COMMENT "Running tests.." 39 | ) 40 | -------------------------------------------------------------------------------- /pytests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware/tdnf/01ee65027aecfa0d2d2bc08dd760e933df9bfe08/pytests/__init__.py -------------------------------------------------------------------------------- /pytests/config-install.json.in: -------------------------------------------------------------------------------- 1 | { 2 | "installed": true, 3 | "project_name": "@PROJECT_NAME@", 4 | "project_version": "@VERSION@", 5 | "specs_dir": "@CMAKE_INSTALL_PREFIX@/share/tdnf/pytests/repo", 6 | "repo_path": "/var/tdnf/pytests/repo", 7 | "test_path": "@CMAKE_INSTALL_PREFIX@/share/tdnf/pytests", 8 | "bin_dir": "@CMAKE_INSTALL_PREFIX@/bin", 9 | "plugin_path": "@CMAKE_INSTALL_PREFIX@/lib/tdnf-plugins", 10 | "automatic_script": "@CMAKE_INSTALL_PREFIX@/bin/tdnf-automatic", 11 | "automatic_conf": "/var/tdnf/pytests/repo/automatic.conf", 12 | "sglversion_pkgname": "tdnf-test-one", 13 | "sglversion2_pkgname": "tdnf-test-two", 14 | "mulversion_pkgname": "tdnf-test-multiversion", 15 | "mulversion_lower": "1.0.1-1", 16 | "mulversion_higher": "1.0.2-1", 17 | "requiring_package": "tdnf-test-dependson-base", 18 | "required_package": "tdnf-test-base", 19 | "dummy_requires_pkgname": "tdnf-test-dummy-requires", 20 | "valgrind_minimum_version": "3.15.0", 21 | "valgrind_minimum_version_aarch64": "3.17.0" 22 | } 23 | -------------------------------------------------------------------------------- /pytests/config.json.in: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "@PROJECT_NAME@", 3 | "project_version": "@VERSION@", 4 | "specs_dir": "@CMAKE_SOURCE_DIR@/pytests/repo", 5 | "repo_path": "@CMAKE_CURRENT_BINARY_DIR@/repo", 6 | "test_path": "@CMAKE_SOURCE_DIR@/pytests", 7 | "build_dir": "@CMAKE_BINARY_DIR@", 8 | "small_cache_path": "@CMAKE_CURRENT_BINARY_DIR@/small_cache/", 9 | "bin_dir": "@CMAKE_BINARY_DIR@/bin", 10 | "plugin_path": "@CMAKE_BINARY_DIR@/plugins/lib", 11 | "automatic_script": "@CMAKE_SOURCE_DIR@/bin/tdnf-automatic", 12 | "automatic_conf": "@CMAKE_SOURCE_DIR@/etc/tdnf/automatic.conf", 13 | "sglversion_pkgname": "tdnf-test-one", 14 | "sglversion2_pkgname": "tdnf-test-two", 15 | "mulversion_pkgname": "tdnf-test-multiversion", 16 | "mulversion_lower": "1.0.1-1", 17 | "mulversion_higher": "1.0.2-1", 18 | "requiring_package": "tdnf-test-dependson-base", 19 | "required_package": "tdnf-test-base", 20 | "dummy_requires_pkgname": "tdnf-test-dummy-requires", 21 | "toolarge_pkgname": "tdnf-test-toolarge", 22 | "valgrind_minimum_version": "3.15.0", 23 | "valgrind_minimum_version_aarch64": "3.17.0" 24 | } 25 | -------------------------------------------------------------------------------- /pytests/mount-small-cache.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## file: mount-small-cache.sh 4 | ## brief: mounts an intentionally small directory for out-of-diskspace tests. 5 | 6 | if [ ${EUID} -ne 0 ]; then 7 | echo "Script must be run as root." 1>&2 8 | exit 1 9 | fi 10 | 11 | ## must match the path set in config.json.in. 12 | small_cache_path="@CMAKE_CURRENT_BINARY_DIR@/small_cache/" 13 | quota_size="1M" 14 | 15 | check_err() { 16 | local rc=$? 17 | if [ $rc -ne 0 ]; then 18 | echo "$1" 1>&2 19 | exit $rc 20 | fi 21 | } 22 | 23 | vdisk="virtual_disks" 24 | ext4_fn="${vdisk}/fs.ext4" 25 | 26 | echo "Creating mount point ..." 27 | if mountpoint ${small_cache_path} &> /dev/null; then 28 | umount ${small_cache_path} 29 | check_err "ERROR: umount ${small_cache_path}" 30 | sync 31 | fi 32 | rm -rf ${vdisk} ${small_cache_path} 33 | mkdir -p ${vdisk} ${small_cache_path} 34 | check_err "ERROR: failed to mkdir ${vdisk} ${small_cache_path}" 35 | 36 | echo "Creating tmpfs ..." 37 | dd if=/dev/zero of=${ext4_fn} bs=${quota_size} count=1 38 | check_err "ERROR: dd failed" 39 | 40 | mkfs.ext4 ${ext4_fn} 41 | check_err "ERROR: mkfs.ext4 failed" 42 | 43 | echo "Mounting tmpfs at ${small_cache_path} ..." 44 | mount -o loop,rw,usrquota,grpquota ${ext4_fn} ${small_cache_path} 45 | check_err "ERROR: failed to mount exf4 tmpfs" 46 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-bad-pre.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-bad-pre spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-bad-pre 6 | Version: 1.0.0 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Test bad install scripts. 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %pre 24 | # fail intentionally 25 | %{_bindir}/false 26 | 27 | %files 28 | 29 | %changelog 30 | * Fri Apr 2 2021 Oliver Kurth 1.0.0-1 31 | initial package to test '--setopt=tsflags=noscripts' 32 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-conflict-file0.spec: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-conflict-file0 3 | Version: 1.0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. Two packages containing one identical file. 13 | 14 | %prep 15 | 16 | %build 17 | 18 | %install 19 | mkdir -p %{buildroot}/usr/lib/conflict 20 | # for a file conflict, cntents of the files need to differ 21 | echo file0 > %{buildroot}/usr/lib/conflict/conflicting-file 22 | 23 | %files 24 | /usr/lib/conflict/conflicting-file 25 | 26 | %changelog 27 | * Tue Jul 06 2021 Oliver Kurth 1.0.1-1 28 | - first version 29 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-conflict-file1.spec: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-conflict-file1 3 | Version: 1.0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. Two packages containing one identical file. 13 | 14 | %prep 15 | 16 | %build 17 | 18 | %install 19 | mkdir -p %{buildroot}/usr/lib/conflict 20 | echo file > %{buildroot}/usr/lib/conflict/conflicting-file 21 | 22 | %files 23 | /usr/lib/conflict/conflicting-file 24 | 25 | %changelog 26 | * Tue Jul 06 2021 Oliver Kurth 1.0.1-1 27 | - first version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-dummy-pretrans.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-dummy-pretrans spec file 3 | # 4 | Summary: Dummy spec file to test pretrans dependencies 5 | Name: tdnf-dummy-pretrans 6 | Version: 1.0 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Dummy spec file to test pretrans dependencies 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Tue Sep 08 2020 Keerthana K 1.0-1 27 | - First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-missing-dep.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-missing spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-missing-dep 6 | Version: 1.0.1 7 | Release: 2 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | # requires something we do not have 15 | Requires: missing 16 | 17 | %description 18 | Part of tdnf test spec. Basic install/remove/upgrade test 19 | 20 | %prep 21 | 22 | %build 23 | 24 | %install 25 | mkdir -p %{buildroot}/lib/systemd/system/ 26 | cat << EOF >> %{buildroot}/lib/systemd/system/%name.service 27 | [Unit] 28 | Description=%name.service for whatprovides test. 29 | 30 | EOF 31 | 32 | %files 33 | /lib/systemd/system/%name.service 34 | 35 | %changelog 36 | * Fri Sep 16 Oliver Kurth 1.0 37 | - Initial build. First version 38 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-multi1.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: multiinstall test 5 | Name: tdnf-multi 6 | Version: 1.0.1 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | # files should not conflict 22 | %install 23 | mkdir -p %{buildroot}/usr/share/multiinstall 24 | touch %{buildroot}/usr/share/multiinstall-%{release} 25 | 26 | %files 27 | /usr/share/multiinstall-%{release} 28 | 29 | %changelog 30 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-1 31 | - Add a service file for whatprovides test. 32 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-multi2.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: multiinstall test 5 | Name: tdnf-multi 6 | Version: 1.0.1 7 | Release: 2 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | # files should not conflict 22 | %install 23 | mkdir -p %{buildroot}/usr/share/multiinstall 24 | touch %{buildroot}/usr/share/multiinstall-%{release} 25 | 26 | %files 27 | /usr/share/multiinstall-%{release} 28 | 29 | %changelog 30 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-2 31 | - bump 32 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-1 33 | - Add a service file for whatprovides test. 34 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-multi3.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: multiinstall test 5 | Name: tdnf-multi 6 | Version: 1.0.1 7 | Release: 3 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | # files should not conflict 22 | %install 23 | mkdir -p %{buildroot}/usr/share/multiinstall 24 | touch %{buildroot}/usr/share/multiinstall-%{release} 25 | 26 | %files 27 | /usr/share/multiinstall-%{release} 28 | 29 | %changelog 30 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-3 31 | - bump 32 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-2 33 | - bump 34 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-1 35 | - Add a service file for whatprovides test. 36 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-multi4.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: multiinstall test 5 | Name: tdnf-multi 6 | Version: 1.0.1 7 | Release: 4 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | # files should not conflict 22 | %install 23 | mkdir -p %{buildroot}/usr/share/multiinstall 24 | touch %{buildroot}/usr/share/multiinstall-%{release} 25 | 26 | %files 27 | /usr/share/multiinstall-%{release} 28 | 29 | %changelog 30 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-4 31 | - bump 32 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-3 33 | - bump 34 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-2 35 | - bump 36 | * Mon Jul 17 2023 Oliver Kurth 1.0.1-1 37 | - Add a service file for whatprovides test. 38 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-repoquery-base.spec: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-repoquery-base 3 | Version: 1.0.1 4 | Release: 2 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. For repoquery tests, other packages will 13 | depend on this in some way. 14 | 15 | %prep 16 | 17 | %build 18 | 19 | %install 20 | mkdir -p %{buildroot}/usr/lib/repoquery 21 | touch %{buildroot}/usr/lib/repoquery/%name 22 | 23 | %files 24 | /usr/lib/repoquery/%name 25 | 26 | %changelog 27 | * Tue Jul 06 2021 Oliver Kurth 1.0.1-2 28 | - first repoquery version 29 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-repoquery-changelog.spec: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-repoquery-changelog 3 | Version: 1.0.1 4 | Release: 2 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. For repoquery tests, other packages will 13 | depend on this in some way. 14 | 15 | %prep 16 | 17 | %build 18 | 19 | %install 20 | mkdir -p %{buildroot}/usr/lib/repoquery 21 | touch %{buildroot}/usr/lib/repoquery/%name 22 | 23 | %files 24 | /usr/lib/repoquery/%name 25 | 26 | %changelog 27 | * Tue Jul 06 2021 Oliver Kurth 1.2.3-4 28 | - needle in a haystack 29 | * Wed Jan 01 2020 John Doe 1.0.0-1 30 | - wrong date, needed for testing. Fedora ignores dates before 31 | some time 2018. 32 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-repoquery-deps.spec.in: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-repoquery-@@dep@@ 3 | Version: 1.0.1 4 | Release: 2 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | @@dep@@: tdnf-repoquery-base 12 | 13 | %description 14 | Part of tdnf test spec. For repoquery tests, this package will 15 | depend on tdnf-repoquery-base (or provide, ...) 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | mkdir -p %{buildroot}/usr/lib/repoquery 23 | touch %{buildroot}/usr/lib/repoquery/%name 24 | 25 | %files 26 | /usr/lib/repoquery/%name 27 | 28 | %changelog 29 | * Tue Jul 06 2021 Oliver Kurth 1.0.1-2 30 | - first repoquery version 31 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-repoquery-queryformat.spec: -------------------------------------------------------------------------------- 1 | Summary: Repoquery Test 2 | Name: tdnf-repoquery-queryformat 3 | Version: 1.0.1 4 | Release: 2 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | Requires: tdnf-test-cleanreq1-required 11 | Conflicts: tdnf-test-conflicts-0 12 | Provides: tdnf-repoquery-queryformat 13 | Obsoletes: tdnf-test-obsoleted 14 | 15 | %description 16 | Part of tdnf test spec. For repoquery tests, other packages will 17 | depend on this in some way. 18 | 19 | %prep 20 | 21 | %build 22 | 23 | %install 24 | mkdir -p %{buildroot}/usr/lib/repoquery 25 | touch %{buildroot}/usr/lib/repoquery/%name 26 | 27 | %files 28 | /usr/lib/repoquery/%name 29 | 30 | %changelog 31 | * Tue Jul 06 2021 Oliver Kurth 1.0.1-2 32 | - first repoquery version 33 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-cleanreq-leaf1.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-cleanreq-leaf1 6 | Version: 1.0.1 7 | Release: 3 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | Requires: tdnf-test-cleanreq-required 14 | 15 | %description 16 | Part of tdnf test spec. Basic install/remove/upgrade test 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | mkdir -p %{buildroot}/lib/cleanreq/ 24 | touch %{buildroot}/lib/cleanreq/%name 25 | 26 | %files 27 | /lib/cleanreq/%name 28 | 29 | %changelog 30 | * Thu Nov 04 2021 Oliver Kurth 1.0.1-3 31 | - clean req test 32 | * Tue Nov 15 2016 Xiaolin Li 1.0.1-2 33 | - Add a service file for whatprovides test. 34 | * Tue Dec 15 2015 Priyesh Padmavilasom 1.0 35 | - Initial build. First version 36 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-cleanreq-leaf2.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-cleanreq-leaf2 6 | Version: 1.0.1 7 | Release: 3 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | Requires: tdnf-test-cleanreq-required 14 | 15 | %description 16 | Part of tdnf test spec. Basic install/remove/upgrade test 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | mkdir -p %{buildroot}/lib/cleanreq/ 24 | touch %{buildroot}/lib/cleanreq/%name 25 | 26 | %files 27 | /lib/cleanreq/%name 28 | 29 | %changelog 30 | * Thu Nov 04 2021 Oliver Kurth 1.0.1-3 31 | - clean req test 32 | * Tue Nov 15 2016 Xiaolin Li 1.0.1-2 33 | - Add a service file for whatprovides test. 34 | * Tue Dec 15 2015 Priyesh Padmavilasom 1.0 35 | - Initial build. First version 36 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-cleanreq-required.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-cleanreq-required 6 | Version: 1.0.1 7 | Release: 3 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | mkdir -p %{buildroot}/lib/cleanreq/ 23 | touch %{buildroot}/lib/cleanreq/required 24 | 25 | %files 26 | /lib/cleanreq/required 27 | 28 | %changelog 29 | * Thu Nov 04 2021 Oliver Kurth 1.0.1-1 30 | - clean req test 31 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-conflicts-0.spec: -------------------------------------------------------------------------------- 1 | Summary: Conflict test spec 2 | Name: tdnf-test-dummy-conflicts-0 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. Basic conflict test. 13 | 14 | %prep 15 | 16 | %build 17 | 18 | %install 19 | 20 | %files 21 | 22 | %changelog 23 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 24 | - First version 25 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-conflicts-1.spec: -------------------------------------------------------------------------------- 1 | Summary: Conflict test spec 2 | Name: tdnf-test-dummy-conflicts-1 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | Conflicts: tdnf-test-dummy-conflicts-0 12 | 13 | %description 14 | Part of tdnf test spec. Basic conflict test. 15 | 16 | %prep 17 | 18 | %build 19 | 20 | %install 21 | 22 | %files 23 | 24 | %changelog 25 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 26 | - First version 27 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-obsoleted.spec: -------------------------------------------------------------------------------- 1 | Summary: Dummy obsoleted spec 2 | Name: tdnf-test-dummy-obsoleted 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | %description 12 | Part of tdnf test spec. This packges will be obsoleted. 13 | 14 | %prep 15 | 16 | %build 17 | 18 | %install 19 | 20 | %files 21 | 22 | %changelog 23 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 24 | - First version 25 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-obsoleting.spec: -------------------------------------------------------------------------------- 1 | Summary: Dummy obsoletes spec 2 | Name: tdnf-test-dummy-obsoleting 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | Provides: tdnf-test-dummy-obsoleted 12 | Obsoletes: tdnf-test-dummy-obsoleted 13 | 14 | %description 15 | Part of tdnf test spec. This package obsoletes the -obsoleted package. 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 27 | - First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-obsoleting3.spec: -------------------------------------------------------------------------------- 1 | Summary: Dummy obsoletes spec 3 2 | Name: tdnf-test-dummy-obsoleting3 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | Provides: tdnf-test-dummy-obsoleted 12 | #Obsoletes: tdnf-test-dummy-obsoleted 13 | 14 | %description 15 | Part of tdnf test spec. This is another package that obsoletes the -obsoleted package. 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 27 | - First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-dummy-requires.spec: -------------------------------------------------------------------------------- 1 | Summary: Dummy requires spec 2 | Name: tdnf-test-dummy-requires 3 | Version: 0.1 4 | Release: 1 5 | Vendor: VMware, Inc. 6 | Distribution: Photon 7 | License: VMware 8 | Url: http://www.vmware.com 9 | Group: Applications/tdnftest 10 | 11 | Requires: dummy-requirement 12 | 13 | %description 14 | Part of tdnf test spec. Basic dummy requirement test. 15 | 16 | %prep 17 | 18 | %build 19 | 20 | %install 21 | 22 | %files 23 | 24 | %changelog 25 | * Fri Aug 07 2020 Shreenidhi Shedi 0.1-1 26 | - First version 27 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-multiversion-1.0.1.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-multiversion spec file version 1.0.1 3 | # 4 | Summary: basic multiversoin install test file. 5 | Name: tdnf-test-multiversion 6 | Version: 1.0.1 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Wed Apr 22 2015 Priyesh Padmavilasom 1.0.1 27 | - Initial build. First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-multiversion-1.0.2.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-multiversion spec file version 1.0.2 3 | # 4 | Summary: basic multiversoin install test file. 5 | Name: tdnf-test-multiversion 6 | Version: 1.0.2 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Wed Apr 22 2015 Priyesh Padmavilasom 1.0.2 27 | - Initial build. First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-noarch.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-noarch 6 | Version: 1.0.1 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | BuildArch: noarch 14 | 15 | %description 16 | Part of tdnf test spec. Basic install/remove/upgrade test 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | mkdir -p %{buildroot}/lib/systemd/system/ 24 | cat << EOF >> %{buildroot}/lib/systemd/system/%{name}.service 25 | [Unit] 26 | Description=%{name} for arch related tests 27 | 28 | EOF 29 | 30 | %files 31 | /lib/systemd/system/%{name}.service 32 | 33 | %changelog 34 | * Mon Oct 10 2022 Oliver Kurth 1.0.1 35 | - Initial build. First version 36 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-one.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-one spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-one 6 | Version: 1.0.1 7 | Release: 2 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | mkdir -p %{buildroot}/lib/systemd/system/ 23 | cat << EOF >> %{buildroot}/lib/systemd/system/tdnf-test-one.service 24 | [Unit] 25 | Description=tdnf-test-one.service for whatprovides test. 26 | 27 | EOF 28 | 29 | %files 30 | /lib/systemd/system/tdnf-test-one.service 31 | 32 | %changelog 33 | * Tue Nov 15 2016 Xiaolin Li 1.0.1-2 34 | - Add a service file for whatprovides test. 35 | * Tue Dec 15 2015 Priyesh Padmavilasom 1.0 36 | - Initial build. First version 37 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-pretrans-one.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-pretrans-1 spec file 3 | # 4 | Summary: Test Requires(pretrans) dependency 5 | Name: tdnf-test-pretrans-one 6 | Version: 1.0 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | Requires(pretrans): tdnf-dummy-pretrans >= 1.0-1 14 | 15 | %description 16 | Test Requires(pretrans) dependency 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | 24 | %files 25 | 26 | %changelog 27 | * Tue Sep 08 2020 Keerthana K 1.0-1 28 | - First version 29 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-pretrans-two.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-pretrans-2 spec file 3 | # 4 | Summary: Test Requires(pretrans) dependency 5 | Name: tdnf-test-pretrans-two 6 | Version: 1.0 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | Requires(pretrans): tdnf-dummy-pretrans < 1.0-2 14 | 15 | %description 16 | Test Requires(pretrans) dependency 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | 24 | %files 25 | 26 | %changelog 27 | * Tue Sep 08 2020 Keerthana K 1.0-1 28 | - First version 29 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-toolarge.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-toolarge spec file 3 | # 4 | Summary: creates a fake random file that is too large for cache dir. 5 | Name: tdnf-test-toolarge 6 | Version: 1.0.1 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Creates a large file to intentionally trigger an 16 | out of disk space error. 17 | 18 | %prep 19 | 20 | %build 21 | 22 | %install 23 | mkdir -p %{buildroot}/lib/toolarge/ 24 | touch %{buildroot}/lib/toolarge/largedata.txt 25 | dd if=/dev/urandom of=%{buildroot}/lib/toolarge/largedata.txt bs=1M count=1 26 | 27 | %files 28 | /lib/toolarge/largedata.txt 29 | 30 | %changelog 31 | * Thu May 23 2022 Preston Narchetti 1.0 32 | - Initial build. First version 33 | 34 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-test-two.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf-test-two spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-test-two 6 | Version: 1.0.1 7 | Release: 1 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | 23 | %files 24 | 25 | %changelog 26 | * Mon May 23 2016 Priyesh Padmavilasom 1.0 27 | - Initial build. First version 28 | -------------------------------------------------------------------------------- /pytests/repo/tdnf-verbose-scripts.spec: -------------------------------------------------------------------------------- 1 | # 2 | # tdnf test spec file 3 | # 4 | Summary: basic install test file. 5 | Name: tdnf-verbose-scripts 6 | Version: 1.0.1 7 | Release: 2 8 | Vendor: VMware, Inc. 9 | Distribution: Photon 10 | License: VMware 11 | Url: http://www.vmware.com 12 | Group: Applications/tdnftest 13 | 14 | %description 15 | Part of tdnf test spec. Basic install/remove/upgrade test 16 | 17 | %prep 18 | 19 | %build 20 | 21 | %install 22 | mkdir -p %{buildroot}/lib/systemd/system/ 23 | echo %{buildroot}/lib/systemd/system/%{name}.service 24 | cat << EOF >> %{buildroot}/lib/systemd/system/%{name}.service 25 | [Unit] 26 | Description=%{name}.service for rpm script test. 27 | 28 | EOF 29 | 30 | %post 31 | echo "echo from post" 32 | echo "echo to stderr from post" >&2 33 | 34 | %postun 35 | echo "echo from postun" 36 | echo "echo to stderr from postun" >&2 37 | 38 | %pre 39 | echo "echo from pre" 40 | echo "echo to stderr from pre" >&2 41 | 42 | %preun 43 | echo "echo from preun" 44 | echo "echo to stderr from preun" >&2 45 | 46 | %files 47 | /lib/systemd/system/%{name}.service 48 | 49 | %changelog 50 | * Tue Jul 11 2023 Oliver Kurth 51 | - test script output redirection 52 | -------------------------------------------------------------------------------- /pytests/repo/updateinfo-1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DISCUS-2015-5-01 5 | etcd 6 | Discus 1 7 | 8 | 9 | 10 | 11 | 12 | update tdnf-test-multiversion to 1.0.2. 13 | 14 | 15 | Discus 1 16 | 17 | tdnf-test-multiversion-1.0.2-1.x86_64.rpm 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /pytests/repo/updateinfo-2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | PHSA-2017-2.0-0001 4 | tdnf-test-multiversion 5 | 7.5 6 | 1 7 | Copyright 2007 Company Inc 8 | 9 | 10 | This update includes a fix for a denial-of-service issue. 11 | 12 | 13 | Photon 1 14 | 15 | tdnf-test-multiversion-1.0.2-1.x86_64.rpm 16 | True 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /pytests/tests/test_assumeno.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | # remove sglversion_pkgname at the beginning of tests 15 | pkgname = utils.config['sglversion_pkgname'] 16 | if utils.check_package(pkgname): 17 | utils.run(['tdnf', 'erase', '-y', pkgname]) 18 | yield 19 | teardown_test(utils) 20 | 21 | 22 | def teardown_test(utils): 23 | pkgname = utils.config['sglversion_pkgname'] 24 | utils.run(['tdnf', 'erase', '-y', pkgname]) 25 | 26 | 27 | def test_assumeno_install(utils): 28 | pkgname = utils.config['sglversion_pkgname'] 29 | utils.run(['tdnf', '--assumeno', 'install', pkgname]) 30 | assert not utils.check_package(pkgname) 31 | 32 | 33 | def test_assumeno_erase(utils): 34 | pkgname = utils.config['sglversion_pkgname'] 35 | utils.run(['tdnf', 'install', '-y', pkgname]) 36 | assert utils.check_package(pkgname) 37 | utils.run(['tdnf', '--assumeno', 'erase', pkgname]) 38 | assert utils.check_package(pkgname) 39 | -------------------------------------------------------------------------------- /pytests/tests/test_auth.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 Broadcom, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | 8 | import base64 9 | import os 10 | import pytest 11 | 12 | from http.server import SimpleHTTPRequestHandler, HTTPServer 13 | from multiprocessing import Process 14 | 15 | 16 | HTTP_PORT = 8088 17 | 18 | USERNAME = "cassian" 19 | PASSWORD = "andor" 20 | AUTH_STRING = "Basic " + base64.b64encode(f"{USERNAME}:{PASSWORD}".encode()).decode() 21 | 22 | 23 | class AuthHandler(SimpleHTTPRequestHandler): 24 | def do_GET(self): 25 | if self.headers.get("Authorization") == AUTH_STRING: 26 | return super().do_GET() 27 | else: 28 | self.send_response(401) 29 | self.send_header("WWW-Authenticate", "Basic realm='Test'") 30 | self.send_header("Content-type", "text/html") 31 | self.end_headers() 32 | self.wfile.write(b"Authentication required") 33 | 34 | 35 | def AuthRepoServer(root, port=HTTP_PORT, interface=''): 36 | addr = (interface, port) 37 | 38 | os.chdir(root) 39 | 40 | httpd = HTTPServer(addr, AuthHandler) 41 | httpd.serve_forever() 42 | 43 | 44 | @pytest.fixture(scope='module', autouse=True) 45 | def start_server(utils): 46 | server = Process(target=AuthRepoServer, 47 | args=(utils.config['repo_path'], )) 48 | server.start() 49 | 50 | yield 51 | 52 | server.terminate() 53 | server.join() 54 | 55 | 56 | @pytest.fixture(scope='function', autouse=True) 57 | def setup_test_function(utils): 58 | pkgname = utils.config["sglversion_pkgname"] 59 | utils.erase_package(pkgname) 60 | yield 61 | utils.erase_package(pkgname) 62 | 63 | 64 | def test_install_package(utils): 65 | pkgname = utils.config["sglversion_pkgname"] 66 | 67 | ret = utils.run(['tdnf', 'install', '--repoid=photon-test-auth', '-y', '--nogpgcheck', pkgname]) 68 | assert ret['retval'] == 0 69 | assert utils.check_package(pkgname) 70 | -------------------------------------------------------------------------------- /pytests/tests/test_baseurls.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | WORKDIR = '/root/baseurls/workdir' 14 | REPOFILENAME = 'baseurls.repo' 15 | REPONAME = 'baseurls-repo' 16 | 17 | 18 | @pytest.fixture(scope='function', autouse=True) 19 | def setup_test(utils): 20 | yield 21 | teardown_test(utils) 22 | 23 | 24 | def teardown_test(utils): 25 | pkgname = utils.config["mulversion_pkgname"] 26 | utils.erase_package(pkgname) 27 | if os.path.isdir(WORKDIR): 28 | shutil.rmtree(WORKDIR) 29 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 30 | if os.path.isfile(filename): 31 | os.remove(filename) 32 | 33 | 34 | def test_multiple_baseurls(utils): 35 | reponame = REPONAME 36 | workdir = WORKDIR 37 | utils.makedirs(workdir) 38 | 39 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 40 | # we should get a 404 for the first url and skip to the next one 41 | baseurls = "http://localhost:8080/doesntexist http://localhost:8080/photon-test" 42 | utils.create_repoconf(filename, baseurls, reponame) 43 | 44 | ret = utils.run(['tdnf', 45 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 46 | 'makecache'], 47 | cwd=workdir) 48 | assert ret['retval'] == 0 49 | 50 | pkgname = utils.config["mulversion_pkgname"] 51 | utils.erase_package(pkgname) 52 | ret = utils.run(['tdnf', 53 | '-y', '--nogpgcheck', 54 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 55 | 'install', pkgname], 56 | cwd=workdir) 57 | assert utils.check_package(pkgname) 58 | -------------------------------------------------------------------------------- /pytests/tests/test_cfgreader.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | 12 | NEW_REPO_FN = 'test.repo' 13 | ORIG_REPO_FN = 'photon-test.repo' 14 | 15 | 16 | def create_repoconf(fn): 17 | content = ''' 18 | [cfg-test] 19 | name= Test Repo 20 | baseurl = http://localhost:8080/photon-test 21 | enabled =1 22 | gpgcheck=0 23 | ''' 24 | with open(fn, 'w') as f: 25 | f.write(content) 26 | 27 | 28 | @pytest.fixture(scope='module', autouse=True) 29 | def setup_test(utils): 30 | global NEW_REPO_FN 31 | global ORIG_REPO_FN 32 | 33 | NEW_REPO_FN = os.path.join(utils.config['repo_path'], 'yum.repos.d', 34 | NEW_REPO_FN) 35 | 36 | ORIG_REPO_FN = os.path.join(utils.config['repo_path'], 'yum.repos.d', 37 | ORIG_REPO_FN) 38 | 39 | create_repoconf(NEW_REPO_FN) 40 | 41 | # take backup of original repo file 42 | os.rename(ORIG_REPO_FN, ORIG_REPO_FN + '.bak') 43 | 44 | yield 45 | 46 | teardown_test(utils) 47 | 48 | 49 | def teardown_test(utils): 50 | os.remove(NEW_REPO_FN) 51 | os.rename(ORIG_REPO_FN + '.bak', ORIG_REPO_FN) 52 | ret = utils.run(['tdnf', 'makecache']) 53 | assert ret['retval'] == 0 54 | 55 | 56 | def test_makecache(utils): 57 | ret = utils.run(['tdnf', 'makecache']) 58 | assert ret['retval'] == 0 59 | for i in ret['stdout']: 60 | if 'Metadata cache created' in i: 61 | return 62 | assert False 63 | 64 | 65 | def test_repolist(utils): 66 | ret = utils.run(['tdnf', 'repolist']) 67 | assert ret['retval'] == 0 68 | for i in ret['stdout']: 69 | if 'cfg-test' in i and 'enabled' in i and 'Test Repo' in i: 70 | return 71 | assert False 72 | -------------------------------------------------------------------------------- /pytests/tests/test_check_local.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import tempfile 11 | import pytest 12 | import shutil 13 | import platform 14 | 15 | ARCH = platform.machine() 16 | 17 | 18 | @pytest.fixture(scope='module', autouse=True) 19 | def setup_test(utils): 20 | yield 21 | teardown_test(utils) 22 | 23 | 24 | def teardown_test(utils): 25 | pass 26 | 27 | 28 | def test_check_local_no_args(utils): 29 | ret = utils.run(['tdnf', 'check-local']) 30 | assert ret['retval'] == 906 31 | 32 | 33 | def test_check_local_with_invalid_dir(utils): 34 | ret = utils.run(['tdnf', 'check-local', '/home/invalid_dir']) 35 | assert ret['retval'] == 1602 36 | 37 | 38 | def test_check_local_empty_directory(utils): 39 | temp_dir = tempfile.TemporaryDirectory() 40 | ret = utils.run(['tdnf', 'check-local', temp_dir.name]) 41 | assert ret['retval'] == 0 42 | 43 | 44 | def test_check_local_with_local_rpm(utils): 45 | with tempfile.TemporaryDirectory() as tmpdir: 46 | dest = os.path.join(tmpdir, 'test.rpm') 47 | src = os.path.join(utils.config['repo_path'], 'build', 'RPMS', ARCH, 'tdnf-test-two-1.0.1-1.{}.rpm'.format(ARCH)) 48 | shutil.copyfile(src, dest) 49 | 50 | ret = utils.run(['tdnf', 'check-local', tmpdir]) 51 | assert ret['retval'] == 0 52 | -------------------------------------------------------------------------------- /pytests/tests/test_check_skip.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_skipobsoletes(utils): 23 | ret = utils.run(['tdnf', 'check', '--skipobsoletes']) 24 | assert ret['retval'] == 1301 25 | assert ' conflicts ' in '\n'.join(ret['stderr']) 26 | assert ' provides ' in '\n'.join(ret['stderr']) 27 | assert ' obsoletes ' not in '\n'.join(ret['stderr']) 28 | 29 | 30 | def test_skipconflicts(utils): 31 | ret = utils.run(['tdnf', 'check', '--skipconflicts']) 32 | assert ret['retval'] == 1301 33 | assert ' obsoletes ' in '\n'.join(ret['stderr']) 34 | assert ' provides ' in '\n'.join(ret['stderr']) 35 | assert ' conflicts ' not in '\n'.join(ret['stderr']) 36 | 37 | 38 | def test_skipconflicts_skipobsoletes(utils): 39 | ret = utils.run(['tdnf', 'check', '--skipconflicts', '--skipobsoletes']) 40 | assert ret['retval'] == 1301 41 | assert ' provides ' in '\n'.join(ret['stderr']) 42 | assert ' conflicts ' not in '\n'.join(ret['stderr']) 43 | assert ' obsoletes ' not in '\n'.join(ret['stderr']) 44 | 45 | 46 | def test_check_no_skip(utils): 47 | ret = utils.run(['tdnf', 'check']) 48 | assert ' obsoletes ' in '\n'.join(ret['stderr']) 49 | assert ' conflicts ' in '\n'.join(ret['stderr']) 50 | assert ' provides ' in '\n'.join(ret['stderr']) 51 | -------------------------------------------------------------------------------- /pytests/tests/test_check_update.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | import shutil 12 | 13 | WORKDIR = '/root/test_config' 14 | TEST_CONF_FILE = 'tdnf.conf' 15 | TEST_CONF_PATH = os.path.join(WORKDIR, TEST_CONF_FILE) 16 | 17 | 18 | @pytest.fixture(scope='module', autouse=True) 19 | def setup_test(utils): 20 | tdnf_conf = os.path.join(utils.config['repo_path'], 'tdnf.conf') 21 | 22 | utils.makedirs(WORKDIR) 23 | shutil.copy(tdnf_conf, TEST_CONF_PATH) 24 | 25 | utils.edit_config({'dnf_check_update_compat': '1'}, section='main', filename=TEST_CONF_PATH) 26 | 27 | yield 28 | teardown_test(utils) 29 | 30 | 31 | def teardown_test(utils): 32 | shutil.rmtree(WORKDIR) 33 | spkg = utils.config["sglversion_pkgname"] 34 | mpkg = utils.config["mulversion_pkgname"] 35 | utils.run(['tdnf', 'erase', '-y', spkg, mpkg]) 36 | 37 | 38 | def test_check_update_no_arg(utils): 39 | ret = utils.run(['tdnf', 'check-update']) 40 | assert ret['retval'] == 0 41 | 42 | 43 | def test_check_update_no_arg_dnf_compat(utils): 44 | ret = utils.run(['tdnf', '--config', TEST_CONF_PATH, 'check-update']) 45 | assert ret['retval'] == 0 46 | 47 | 48 | def test_check_update_invalid_args(utils): 49 | ret = utils.run(['tdnf', 'check-update', 'abcd', '1234']) 50 | assert ret['retval'] == 0 51 | 52 | 53 | def test_check_update_multi_version_package(utils): 54 | package = utils.config["mulversion_pkgname"] + '-' + utils.config["mulversion_lower"] 55 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', package]) 56 | assert utils.check_package(utils.config["mulversion_pkgname"]) 57 | 58 | ret = utils.run(['tdnf', 'check-update', utils.config["mulversion_pkgname"]]) 59 | assert len(ret['stdout']) > 0 60 | assert ret['retval'] == 0 61 | 62 | 63 | def test_check_update_multi_version_package_dnf_compat(utils): 64 | package = utils.config["mulversion_pkgname"] + '-' + utils.config["mulversion_lower"] 65 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', package]) 66 | assert utils.check_package(utils.config["mulversion_pkgname"]) 67 | 68 | ret = utils.run(['tdnf', '--config', TEST_CONF_PATH, 'check-update']) 69 | assert len(ret['stdout']) > 0 70 | assert ret['retval'] == 100 71 | 72 | 73 | def test_check_update_single_version_package(utils): 74 | package = utils.config["sglversion_pkgname"] 75 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', package]) 76 | assert ret['retval'] == 0 77 | 78 | ret = utils.run(['tdnf', 'check-update', package]) 79 | assert len(ret['stdout']) == 0 80 | -------------------------------------------------------------------------------- /pytests/tests/test_checksum.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 - 2022 VMware, Inc. All Rights Reserved. 2 | # 3 | # Licensed under the GNU General Public License v2 (the "License"); 4 | # you may not use this file except in compliance with the License. The terms 5 | # of the License are located in the COPYING file of this distribution. 6 | # 7 | 8 | import os 9 | import shutil 10 | import filecmp 11 | import glob 12 | import platform 13 | import pytest 14 | 15 | WORKDIR = '/root/repofrompath/workdir' 16 | ARCH = platform.machine() 17 | 18 | 19 | @pytest.fixture(scope='module', autouse=True) 20 | def setup_test(utils): 21 | yield 22 | teardown_test(utils) 23 | 24 | 25 | def teardown_test(utils): 26 | utils.run(['tdnf', 'erase', '-y', 'tdnf-test-one']) 27 | if os.path.isdir(WORKDIR): 28 | shutil.rmtree(WORKDIR) 29 | 30 | 31 | def enable_and_create_repo(utils): 32 | workdir = WORKDIR 33 | utils.makedirs(workdir) 34 | reponame = 'photon-test-sha512' 35 | 36 | ret = utils.run(['tdnf', '-v', '--disablerepo=*', '--enablerepo=photon-test-sha512', 'makecache']) 37 | assert ret['retval'] == 0 38 | 39 | ret = utils.run(['tdnf', '--repo={}'.format(reponame), 40 | '--download-metadata', 41 | 'reposync'], 42 | cwd=workdir) 43 | assert ret['retval'] == 0 44 | synced_dir = os.path.join(workdir, reponame) 45 | assert os.path.isdir(synced_dir) 46 | assert os.path.isdir(os.path.join(synced_dir, 'repodata')) 47 | assert os.path.isfile(os.path.join(synced_dir, 'repodata', 'repomd.xml')) 48 | 49 | 50 | def copy_rpm(workdir, orig_pkg, copy_pkg): 51 | 52 | orig_path = glob.glob(f"{workdir}/{orig_pkg}*.rpm") 53 | copy_path = glob.glob(f"{workdir}/{copy_pkg}*.rpm") 54 | 55 | if not filecmp.cmp(copy_path[0], orig_path[0]): 56 | shutil.copy2(copy_path[0], orig_path[0]) 57 | 58 | 59 | # install package with SHA512 60 | def test_install_package_with_sha512_checksum(utils): 61 | ret = utils.run(['tdnf', 'erase', '-y', 'tdnf-test-one']) 62 | assert ret['retval'] == 0 63 | 64 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', 'install', '-y', 'tdnf-test-one', '--enablerepo=photon-test-sha512']) 65 | assert ret['retval'] == 0 66 | 67 | 68 | # install package with incorrect SHA512 69 | def test_install_package_with_incorrect_sha512_checksum(utils): 70 | workdir = WORKDIR 71 | reponame = 'photon-test-sha512' 72 | synced_dir = os.path.join(workdir, reponame) 73 | rpm_dir = os.path.join(synced_dir, 'RPMS') 74 | rpm_dir = os.path.join(rpm_dir, ARCH) 75 | 76 | enable_and_create_repo(utils) 77 | copy_rpm(rpm_dir, 'tdnf-test-one', 'tdnf-test-two') 78 | 79 | ret = utils.run(['tdnf', 80 | '--repofrompath=synced-repo,{}'.format(synced_dir), 81 | '--repo=synced-repo', 82 | 'makecache'], 83 | cwd=workdir) 84 | assert ret['retval'] == 0 85 | 86 | ret = utils.run(['tdnf', 'erase', '-y', 'tdnf-test-one'], cwd=workdir) 87 | assert ret['retval'] == 0 88 | 89 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', '--repofrompath=synced-repo,{}'.format(synced_dir), '--repo=synced-repo', 'install', '-y', 'tdnf-test-one'], cwd=workdir) 90 | assert ret['retval'] == 1528 91 | -------------------------------------------------------------------------------- /pytests/tests/test_clean.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_clean_no_args(utils): 23 | ret = utils.run(['tdnf', 'clean']) 24 | assert ret['retval'] == 903 25 | 26 | 27 | def test_clean_invalid_arg(utils): 28 | ret = utils.run(['tdnf', 'clean', 'abcde']) 29 | assert ret['retval'] == 901 30 | 31 | 32 | def test_clean_packages(utils): 33 | ret = utils.run(['tdnf', 'clean', 'packages']) 34 | assert ret['retval'] == 0 35 | 36 | 37 | def test_clean_dbcache(utils): 38 | ret = utils.run(['tdnf', 'clean', 'dbcache']) 39 | assert ret['retval'] == 0 40 | 41 | 42 | def test_clean_metadata(utils): 43 | ret = utils.run(['tdnf', 'clean', 'metadata']) 44 | assert ret['retval'] == 0 45 | 46 | 47 | def test_clean_expire_cache(utils): 48 | ret = utils.run(['tdnf', 'clean', 'expire-cache']) 49 | assert ret['retval'] == 0 50 | 51 | 52 | def test_clean_plugins(utils): 53 | ret = utils.run(['tdnf', 'clean', 'plugins']) 54 | assert ret['retval'] == 1016 55 | 56 | 57 | def test_clean_all(utils): 58 | utils.run(['tdnf', 'makecache']) 59 | ret = utils.run(['tdnf', 'clean', 'all']) 60 | assert ret['retval'] == 0 61 | 62 | 63 | def test_clean_all_clean_already(utils): 64 | utils.run(['tdnf', 'makecache']) 65 | utils.run(['tdnf', 'clean', 'all']) 66 | ret = utils.run(['tdnf', 'clean', 'all']) 67 | assert ret['retval'] == 0 68 | 69 | 70 | def test_clean_install_and_clean(utils): 71 | utils.run(['tdnf', 'makecache']) 72 | pkgname = utils.config["mulversion_pkgname"] 73 | utils.erase_package(pkgname) 74 | utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkgname]) 75 | 76 | ret = utils.run(['tdnf', 'clean', 'all']) 77 | assert ret['retval'] == 0 78 | -------------------------------------------------------------------------------- /pytests/tests/test_config.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | import shutil 12 | 13 | WORKDIR = '/root/test_config' 14 | TEST_CONF_FILE = 'tdnf.conf' 15 | TEST_REPO = 'photon-test' 16 | TEST_REPO_FILE = TEST_REPO + '.repo' 17 | TEST_CONF_PATH = os.path.join(WORKDIR, TEST_CONF_FILE) 18 | TEST_REPO_PATH = os.path.join(WORKDIR, TEST_REPO_FILE) 19 | 20 | 21 | @pytest.fixture(scope='module', autouse=True) 22 | def setup_test(utils): 23 | tdnf_conf = os.path.join(utils.config['repo_path'], 'tdnf.conf') 24 | tdnf_repo = os.path.join(utils.tdnf_config.get('main', 'repodir'), 'photon-test.repo') 25 | 26 | utils.makedirs(WORKDIR) 27 | shutil.copy(tdnf_conf, TEST_CONF_PATH) 28 | shutil.copy(tdnf_repo, TEST_REPO_PATH) 29 | 30 | utils.edit_config({'repodir': WORKDIR}, section='main', filename=TEST_CONF_PATH) 31 | 32 | utils.edit_config({'enabled': '1'}, section=TEST_REPO, filename=TEST_REPO_PATH) 33 | 34 | yield 35 | teardown_test(utils) 36 | 37 | 38 | def teardown_test(utils): 39 | shutil.rmtree(WORKDIR) 40 | pkg = utils.config['sglversion_pkgname'] 41 | utils.run(['tdnf', 'erase', '-y', pkg]) 42 | 43 | 44 | def test_config_invalid(utils): 45 | spkg = utils.config['sglversion_pkgname'] 46 | ret = utils.run(['tdnf', '--config', os.path.join(WORKDIR, 'test123.conf'), 'list', spkg]) 47 | assert ret['retval'] == 1602 48 | 49 | 50 | def test_config_list(utils): 51 | spkg = utils.config['sglversion_pkgname'] 52 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 53 | assert ret['retval'] == 0 54 | ret = utils.run(['tdnf', '--config', TEST_CONF_PATH, 'list', spkg]) 55 | assert ret['retval'] == 0 56 | 57 | 58 | def test_config_list_with_disable_repos(utils): 59 | spkg = utils.config['sglversion_pkgname'] 60 | ret = utils.run(['tdnf', '--disablerepo=*', '--config', TEST_CONF_PATH, 'list', spkg]) 61 | assert ret['retval'] == 0 62 | 63 | for line in ret['stdout']: 64 | if not line or '@System' in line: 65 | continue 66 | assert (False) # force fail test 67 | 68 | 69 | def test_config_invaid_repodir(utils): 70 | pkg = utils.config['sglversion_pkgname'] 71 | utils.edit_config({'repodir': '/etc/invalid'}, section='main', filename=TEST_CONF_PATH) 72 | ret = utils.run(['tdnf', '--config', TEST_CONF_PATH, 'list', pkg]) 73 | assert ret['retval'] == 1005 74 | 75 | 76 | def test_config_reposdir(utils): 77 | pkg = utils.config['sglversion_pkgname'] 78 | utils.edit_config({'reposdir': WORKDIR, 'repodir': None}, section='main', filename=TEST_CONF_PATH) 79 | ret = utils.run(['tdnf', '--config', TEST_CONF_PATH, 'list', pkg]) 80 | assert ret['retval'] == 0 81 | -------------------------------------------------------------------------------- /pytests/tests/test_conflict.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | pkg0 = "tdnf-conflict-file0" 12 | pkg1 = "tdnf-conflict-file1" 13 | 14 | 15 | @pytest.fixture(scope='function', autouse=True) 16 | def setup_test(utils): 17 | yield 18 | teardown_test(utils) 19 | 20 | 21 | def teardown_test(utils): 22 | utils.run(['tdnf', 'erase', '-y', pkg0]) 23 | utils.run(['tdnf', 'erase', '-y', pkg1]) 24 | 25 | 26 | def test_install_conflict_file(utils): 27 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkg0]) 28 | print(ret) 29 | assert utils.check_package(pkg0) 30 | 31 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkg1]) 32 | print(ret) 33 | assert ret['retval'] == 1525 34 | assert not utils.check_package(pkg1) 35 | 36 | 37 | def test_install_conflict_file_atonce(utils): 38 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkg0, pkg1]) 39 | print(ret) 40 | assert ret['retval'] == 1525 41 | assert not utils.check_package(pkg0) 42 | assert not utils.check_package(pkg1) 43 | -------------------------------------------------------------------------------- /pytests/tests/test_count.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_count(utils): 23 | ret = utils.run(['tdnf', 'count']) 24 | assert ret['retval'] == 0 25 | 26 | 27 | # memcheck 28 | def test_count_memcheck(utils): 29 | ret = utils.run_memcheck(['tdnf', 'count']) 30 | assert ret['retval'] == 0 31 | -------------------------------------------------------------------------------- /pytests/tests/test_downgrade.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | mpkg = utils.config['mulversion_pkgname'] 20 | utils.run(['tdnf', 'erase', '-y', mpkg]) 21 | 22 | 23 | def test_downgrade_no_arg(utils): 24 | ret = utils.run(['tdnf', 'downgrade']) 25 | assert ret['retval'] == 1011 26 | 27 | 28 | def test_downgrade_install(utils): 29 | mpkg = utils.config['mulversion_pkgname'] 30 | ret = utils.run(['tdnf', 'install', '-y', mpkg]) 31 | assert ret['retval'] == 0 32 | ret = utils.run(['tdnf', 'downgrade', '-y', mpkg]) 33 | assert ret['retval'] == 0 34 | 35 | 36 | def test_downgrade_with_lower_version(utils): 37 | mpkg = utils.config['mulversion_pkgname'] 38 | mpkg_lower = utils.config['mulversion_lower'] 39 | ret = utils.run(['tdnf', 'install', '-y', mpkg + '-' + mpkg_lower]) 40 | assert ret['retval'] == 0 41 | ret = utils.run(['tdnf', 'downgrade', '-y', mpkg]) 42 | assert ret['retval'] == 0 43 | 44 | 45 | def test_downgrade_with_higher_version(utils): 46 | mpkg = utils.config['mulversion_pkgname'] 47 | ret = utils.run(['tdnf', 'install', '-y', mpkg]) 48 | assert ret['retval'] == 0 49 | mpkg_lower = utils.config['mulversion_lower'] 50 | ret = utils.run(['tdnf', 'downgrade', '-y', mpkg + '-' + mpkg_lower]) 51 | assert ret['retval'] == 0 52 | 53 | 54 | def test_downgrade_with_invalid_version(utils): 55 | mpkg = utils.config['mulversion_pkgname'] 56 | ret = utils.run(['tdnf', 'downgrade', '-y', mpkg + '-123.123.123']) 57 | assert ret['retval'] == 1011 58 | 59 | 60 | def test_downgrade_invalid_pkg_name(utils): 61 | ret = utils.run(['tdnf', 'downgrade', '-y', 'invalid_pkg_name']) 62 | assert ret['retval'] == 1011 63 | -------------------------------------------------------------------------------- /pytests/tests/test_erase.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 - 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_erase_no_arg(utils): 23 | ret = utils.run(['tdnf', 'erase']) 24 | assert ret['retval'] == 1001 25 | 26 | 27 | def test_erase_invalid_package(utils): 28 | ret = utils.run(['tdnf', 'erase', 'invalid_package']) 29 | assert ret['retval'] == 1011 30 | 31 | 32 | def test_erase_package_with_version_suffix(utils): 33 | pkgname = utils.config["mulversion_pkgname"] 34 | pkgversion = utils.config["mulversion_lower"] 35 | utils.install_package(pkgname, pkgversion) 36 | 37 | utils.run(['tdnf', 'erase', '-y', pkgname + '-' + pkgversion]) 38 | assert not utils.check_package(pkgname) 39 | 40 | 41 | def test_erase_package_without_version_suffix(utils): 42 | pkgname = utils.config["mulversion_pkgname"] 43 | utils.install_package(pkgname) 44 | 45 | utils.run(['tdnf', 'erase', '-y', pkgname]) 46 | assert not utils.check_package(pkgname) 47 | 48 | 49 | def test_erase_memcheck(utils): 50 | pkgname = utils.config["mulversion_pkgname"] 51 | utils.install_package(pkgname) 52 | 53 | utils.run_memcheck(['tdnf', 'erase', '-y', pkgname]) 54 | assert not utils.check_package(pkgname) 55 | -------------------------------------------------------------------------------- /pytests/tests/test_list.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='function', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | mpkg = utils.config["mulversion_pkgname"] 20 | spkg = utils.config["sglversion_pkgname"] 21 | utils.run(['tdnf', 'erase', '-y', mpkg, spkg]) 22 | 23 | 24 | def helper_test_list_sub_cmd(utils, sub_cmd): 25 | ret = utils.run(['tdnf', 'list', sub_cmd]) 26 | assert ret['retval'] == 0 27 | ret = utils.run(['tdnf', 'list', sub_cmd, utils.config["sglversion_pkgname"]]) 28 | assert ret['retval'] == 0 29 | ret = utils.run(['tdnf', 'list', sub_cmd, 'invalid_package']) 30 | assert ret['retval'] == 1011 31 | 32 | 33 | def test_list_top(utils): 34 | spkg = utils.config["sglversion_pkgname"] 35 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 36 | assert ret['retval'] == 0 37 | 38 | ret = utils.run(['tdnf', 'list']) 39 | assert ret['retval'] == 0 40 | ret = utils.run(['tdnf', 'list', utils.config["sglversion_pkgname"]]) 41 | assert ret['retval'] == 0 42 | ret = utils.run(['tdnf', 'list', 'invalid_package']) 43 | assert ret['retval'] == 1011 44 | 45 | 46 | def test_list_sub_cmd(utils): 47 | spkg = utils.config["sglversion_pkgname"] 48 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 49 | assert ret['retval'] == 0 50 | 51 | helper_test_list_sub_cmd(utils, 'all') 52 | helper_test_list_sub_cmd(utils, 'installed') 53 | helper_test_list_sub_cmd(utils, 'available') 54 | helper_test_list_sub_cmd(utils, 'obsoletes') 55 | helper_test_list_sub_cmd(utils, 'extras') 56 | helper_test_list_sub_cmd(utils, 'recent') 57 | 58 | 59 | def test_list_options(utils): 60 | spkg = utils.config["sglversion_pkgname"] 61 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 62 | assert ret['retval'] == 0 63 | 64 | helper_test_list_sub_cmd(utils, '--all') 65 | helper_test_list_sub_cmd(utils, '--installed') 66 | helper_test_list_sub_cmd(utils, '--available') 67 | helper_test_list_sub_cmd(utils, '--obsoletes') 68 | helper_test_list_sub_cmd(utils, '--extras') 69 | helper_test_list_sub_cmd(utils, '--recent') 70 | 71 | 72 | def test_list_notinstalled(utils): 73 | mpkg = utils.config["mulversion_pkgname"] 74 | mpkg_version = utils.config["mulversion_lower"] 75 | spkg = utils.config["sglversion_pkgname"] 76 | 77 | ret = utils.run(['tdnf', 'list', 'upgrades']) 78 | assert ret['retval'] == 0 79 | 80 | utils.run(['tdnf', 'install', '-y', '--nogpgcheck', mpkg + '-' + mpkg_version]) 81 | ret = utils.run(['tdnf', 'list', 'upgrades', mpkg]) 82 | assert len(ret['stdout']) == 1 83 | 84 | for cmd in ['updates', 'upgrades', 'downgrades', '--updates', '--upgrades', '--downgrades']: 85 | ret = utils.run(['tdnf', 'list', cmd, 'invalid_package']) 86 | assert ret['retval'] == 1011 87 | 88 | # spkg is not installed, expect error 89 | ret = utils.run(['tdnf', 'list', cmd, spkg]) 90 | assert ret['retval'] == 1011 91 | -------------------------------------------------------------------------------- /pytests/tests/test_locks.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | import errno 12 | import shutil 13 | 14 | TESTREPO = 'photon-test' 15 | 16 | 17 | @pytest.fixture(scope='function', autouse=True) 18 | def setup_test(utils): 19 | yield 20 | teardown_test(utils) 21 | 22 | 23 | def teardown_test(utils): 24 | dirname = os.path.join(utils.config['repo_path'], 'locks.d') 25 | if os.path.isdir(dirname): 26 | shutil.rmtree(dirname) 27 | 28 | utils.erase_package(utils.config["sglversion_pkgname"]) 29 | utils.erase_package(utils.config["mulversion_pkgname"]) 30 | 31 | 32 | # helper to create directory tree without complains when it exists: 33 | def makedirs(d): 34 | try: 35 | os.makedirs(d) 36 | except OSError as e: 37 | if e.errno != errno.EEXIST: 38 | raise 39 | 40 | 41 | def set_locks_file(utils, value): 42 | dirname = os.path.join(utils.config['repo_path'], 'locks.d') 43 | makedirs(dirname) 44 | filename = os.path.join(dirname, 'test.conf') 45 | with open(filename, 'w') as f: 46 | f.write(value) 47 | 48 | 49 | def test_locks_conf_erase(utils): 50 | pkgname = utils.config["sglversion_pkgname"] 51 | set_locks_file(utils, pkgname) 52 | utils.install_package(pkgname) 53 | 54 | # sanity check 55 | assert utils.check_package(pkgname) 56 | 57 | # test - uninstalling should fail 58 | utils.run(['tdnf', '-y', '--nogpgcheck', 'remove', pkgname]) 59 | assert utils.check_package(pkgname) 60 | 61 | 62 | def test_locks_conf_update(utils): 63 | pkgname = utils.config["mulversion_pkgname"] 64 | version_low = utils.config["mulversion_lower"] 65 | set_locks_file(utils, pkgname) 66 | 67 | utils.install_package(pkgname, pkgversion=version_low) 68 | assert utils.check_package(pkgname) 69 | 70 | # test - update should fail 71 | utils.run(['tdnf', '-y', '--nogpgcheck', 'update', pkgname]) 72 | assert utils.check_package(pkgname, version=version_low) 73 | -------------------------------------------------------------------------------- /pytests/tests/test_mark.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='function', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pkgname1 = utils.config["mulversion_pkgname"] 20 | pkgname2 = utils.config["sglversion_pkgname"] 21 | pkgname3 = utils.config["sglversion2_pkgname"] 22 | for pkg in [pkgname1, pkgname2, pkgname3]: 23 | utils.erase_package(pkg) 24 | 25 | 26 | # mark autoinstalled package as user installed, 27 | # should not be removed on autoremove 28 | def test_mark_install(utils): 29 | pkgname = 'tdnf-test-cleanreq-leaf1' 30 | pkgname_req = 'tdnf-test-cleanreq-required' 31 | utils.install_package(pkgname) 32 | 33 | assert utils.check_package(pkgname_req) 34 | 35 | ret = utils.run(['tdnf', 'mark', 'install', pkgname_req]) 36 | assert ret['retval'] == 0 37 | 38 | utils.run(['tdnf', '-y', 'autoremove', pkgname]) 39 | 40 | assert not utils.check_package(pkgname) 41 | # actual test - pkg should still be there: 42 | assert utils.check_package(pkgname_req) 43 | 44 | 45 | # dependency already installed, hence would not be removed 46 | # on autoremove, but should be if we mark it auto installed: 47 | def test_mark_remove(utils): 48 | pkgname = 'tdnf-test-cleanreq-leaf1' 49 | pkgname_req = 'tdnf-test-cleanreq-required' 50 | utils.install_package(pkgname_req) 51 | utils.install_package(pkgname) 52 | 53 | assert utils.check_package(pkgname_req) 54 | 55 | ret = utils.run(['tdnf', 'mark', 'remove', pkgname_req]) 56 | assert ret['retval'] == 0 57 | 58 | utils.run(['tdnf', '-y', 'autoremove', pkgname]) 59 | 60 | assert not utils.check_package(pkgname) 61 | # actual test - pkg should be removed: 62 | assert not utils.check_package(pkgname_req) 63 | -------------------------------------------------------------------------------- /pytests/tests/test_minversions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | import shutil 12 | 13 | TESTREPO = 'photon-test' 14 | 15 | 16 | @pytest.fixture(scope='function', autouse=True) 17 | def setup_test(utils): 18 | yield 19 | teardown_test(utils) 20 | 21 | 22 | def teardown_test(utils): 23 | pkgname = utils.config["mulversion_pkgname"] 24 | utils.erase_package(pkgname) 25 | 26 | dirname = os.path.join(utils.config['repo_path'], 'minversions.d') 27 | if os.path.isdir(dirname): 28 | shutil.rmtree(dirname) 29 | 30 | utils.edit_config({'minversions': None}) 31 | 32 | 33 | def set_minversions_conf(utils, value): 34 | utils.edit_config({'minversions': value}) 35 | 36 | 37 | def set_minversions_file(utils, value): 38 | dirname = os.path.join(utils.config['repo_path'], 'minversions.d') 39 | utils.makedirs(dirname) 40 | filename = os.path.join(dirname, 'test.conf') 41 | with open(filename, 'w') as f: 42 | f.write(value) 43 | 44 | 45 | def test_minversions_conf(utils): 46 | pkgname = utils.config["mulversion_pkgname"] 47 | set_minversions_conf(utils, "{}={}".format(pkgname, utils.config["mulversion_higher"])) 48 | utils.install_package(pkgname) 49 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', 'downgrade', pkgname]) 50 | assert ret['retval'] == 1301 51 | assert 'disabled' in "\n".join(ret['stderr']) 52 | 53 | 54 | def test_minversions_conf_multiple(utils): 55 | pkgname = utils.config["mulversion_pkgname"] 56 | set_minversions_conf(utils, "bogus=1.2.3 {}={}".format(pkgname, utils.config["mulversion_higher"])) 57 | utils.install_package(pkgname) 58 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', 'downgrade', pkgname]) 59 | assert ret['retval'] == 1301 60 | assert 'disabled' in "\n".join(ret['stderr']) 61 | 62 | 63 | def test_minversions_file(utils): 64 | pkgname = utils.config["mulversion_pkgname"] 65 | set_minversions_file(utils, "{}={}".format(pkgname, utils.config["mulversion_higher"])) 66 | utils.install_package(pkgname) 67 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', 'downgrade', pkgname]) 68 | assert ret['retval'] == 1301 69 | assert 'disabled' in "\n".join(ret['stderr']) 70 | 71 | 72 | def test_minversions_file_multiple(utils): 73 | pkgname = utils.config["mulversion_pkgname"] 74 | set_minversions_file(utils, "bogus=1.2.3\n{}={}".format(pkgname, utils.config["mulversion_higher"])) 75 | utils.install_package(pkgname) 76 | ret = utils.run(['tdnf', '-y', '--nogpgcheck', 'downgrade', pkgname]) 77 | assert ret['retval'] == 1301 78 | -------------------------------------------------------------------------------- /pytests/tests/test_mirrorlist.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Broadcom, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | WORKDIR = '/root/mirrortest/workdir' 14 | REPONAME = 'mirrortest' 15 | REPOFILENAME = f"{REPONAME}.repo" 16 | MIRRORLIST_FILENAME = "mirror.list" 17 | 18 | 19 | @pytest.fixture(scope='function', autouse=True) 20 | def setup_test(utils): 21 | yield 22 | teardown_test(utils) 23 | 24 | 25 | def teardown_test(utils): 26 | pkgname = utils.config["mulversion_pkgname"] 27 | utils.erase_package(pkgname) 28 | if os.path.isdir(WORKDIR): 29 | shutil.rmtree(WORKDIR) 30 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 31 | if os.path.isfile(filename): 32 | os.remove(filename) 33 | 34 | 35 | def create_repo_conf(repos, reposdir="/etc/yum.repos.d", insecure=False): 36 | """ 37 | Create .repo file as per configurations passed. 38 | Parameters: 39 | - repos: Dictionary containing repo_id as key and value as dictionary containing repo configurations. 40 | Ex: {'repo_id1': {'baseurl': 'https://foo/bar', 'enabled': 0}, 'repo_id2': {'basurl': '/mnt/media/RPMS', 'enabled': 1}} 41 | - reposdir (Optional): Parent dir where .repo needs to be placed. Default Value - /etc/yum.repos.d/{repo_name}.repo 42 | Returns: 43 | - None 44 | """ 45 | os.makedirs(reposdir, exist_ok=True) 46 | for repo in repos: 47 | if insecure: 48 | repos[repo]["sslverify"] = 0 49 | with open(os.path.join(reposdir, f"{repo}.repo"), "w", encoding="utf-8") as repo_file: 50 | repo_file.write(f"[{repo}]\n") 51 | for key, value in repos[repo].items(): 52 | repo_file.write(f"{key}={value}\n") 53 | 54 | 55 | def test_mirrrorlist(utils): 56 | reponame = REPONAME 57 | workdir = WORKDIR 58 | utils.makedirs(workdir) 59 | mirrorlist_path = os.path.join(workdir, MIRRORLIST_FILENAME) 60 | 61 | # we should get a 404 for the first url and skip to the next one 62 | baseurls = ["http://localhost:8080/doesntexist", "http://localhost:8080/photon-test"] 63 | with open(mirrorlist_path, "wt") as f: 64 | for url in baseurls: 65 | f.write(f"{url}\n") 66 | 67 | create_repo_conf({reponame: {'enabled': 1, 'gpgcheck:': 0, 'mirrorlist': f"file://{mirrorlist_path}"}}, 68 | os.path.join(utils.config['repo_path'], "yum.repos.d"), 69 | True) 70 | 71 | ret = utils.run(['tdnf', 72 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 73 | 'makecache'], 74 | cwd=workdir) 75 | assert ret['retval'] == 0 76 | 77 | pkgname = utils.config["mulversion_pkgname"] 78 | utils.erase_package(pkgname) 79 | ret = utils.run(['tdnf', 80 | '-y', '--nogpgcheck', 81 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 82 | 'install', pkgname], 83 | cwd=workdir) 84 | assert utils.check_package(pkgname) 85 | -------------------------------------------------------------------------------- /pytests/tests/test_noscripts.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 - 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pkgname = 'tdnf-bad-pre' 20 | utils.run(['tdnf', 'erase', '-y', pkgname]) 21 | 22 | 23 | # Verify that the package is really bad: 24 | def test_install_normal(utils): 25 | pkgname = 'tdnf-bad-pre' 26 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkgname]) 27 | assert ret['retval'] == 1525 28 | 29 | 30 | def test_install_noscripts(utils): 31 | pkgname = 'tdnf-bad-pre' 32 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', 33 | '--setopt=tsflags=noscripts', pkgname]) 34 | assert ret['retval'] == 0 35 | -------------------------------------------------------------------------------- /pytests/tests/test_pretrans.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def install_dummy_pretrans_dependency(utils): 23 | utils.run(['tdnf', 'install', '-y', 'tdnf-dummy-pretrans']) 24 | 25 | 26 | def remove_dummy_pretrans_dependency(utils): 27 | utils.run(['tdnf', 'remove', '-y', 'tdnf-dummy-pretrans']) 28 | 29 | 30 | def test_install_pretrans_lessthan_fail(utils): 31 | remove_dummy_pretrans_dependency(utils) 32 | ret = utils.run(['tdnf', 'install', '-y', 'tdnf-test-pretrans-one']) 33 | assert ret['stderr'][0].startswith('Detected rpm pre-transaction dependency') 34 | assert ret['retval'] == 1515 35 | 36 | 37 | def test_install_pretrans_greaterthan_fail(utils): 38 | remove_dummy_pretrans_dependency(utils) 39 | ret = utils.run(['tdnf', 'install', '-y', 'tdnf-test-pretrans-two']) 40 | assert ret['stderr'][0].startswith('Detected rpm pre-transaction dependency') 41 | assert ret['retval'] == 1515 42 | 43 | 44 | def test_install_pretrans_lessthan_success(utils): 45 | install_dummy_pretrans_dependency(utils) 46 | ret = utils.run(['tdnf', 'install', '-y', 'tdnf-test-pretrans-one']) 47 | assert ret['retval'] == 0 48 | 49 | 50 | def test_install_pretrans_greaterthan_success(utils): 51 | install_dummy_pretrans_dependency(utils) 52 | ret = utils.run(['tdnf', 'install', '-y', 'tdnf-test-pretrans-two']) 53 | assert ret['retval'] == 0 54 | -------------------------------------------------------------------------------- /pytests/tests/test_priority.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Broadcom, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | REPODIR = "/root/priority/repo" 14 | REPONAME = "priority-test" 15 | REPOFILENAME = f"{REPONAME}.repo" 16 | 17 | 18 | @pytest.fixture(scope='function', autouse=True) 19 | def setup_test(utils): 20 | 21 | os.makedirs(REPODIR, exist_ok=True) 22 | 23 | yield 24 | teardown_test(utils) 25 | 26 | 27 | def teardown_test(utils): 28 | if os.path.isdir(REPODIR): 29 | shutil.rmtree(REPODIR) 30 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 31 | if os.path.isfile(filename): 32 | os.remove(filename) 33 | 34 | 35 | def test_priority(utils): 36 | pkgname = utils.config['mulversion_pkgname'] 37 | pkgname_low = pkgname + "=" + utils.config['mulversion_lower'] 38 | ret = utils.run(["tdnf", 39 | "-y", "--nogpgcheck", 40 | "--downloadonly", f"--downloaddir={REPODIR}", 41 | "install", pkgname_low], 42 | ) 43 | assert ret['retval'] == 0 44 | 45 | ret = utils.run(["createrepo", "."], cwd=REPODIR) 46 | assert ret['retval'] == 0 47 | 48 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 49 | baseurl = "file://{}".format(REPODIR) 50 | 51 | utils.create_repoconf(filename, baseurl, REPONAME) 52 | utils.edit_config({'priority': "25"}, repo=REPONAME) 53 | 54 | ret = utils.run(["tdnf", 55 | "-y", "--nogpgcheck", 56 | "install", pkgname], 57 | cwd=REPODIR) 58 | assert ret['retval'] == 0 59 | 60 | utils.check_package(pkgname, version=utils.config['mulversion_lower']) 61 | -------------------------------------------------------------------------------- /pytests/tests/test_provides.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_provides_no_arg(utils): 23 | ret = utils.run(['tdnf', 'provides']) 24 | assert ret['retval'] == 907 25 | 26 | 27 | def test_provides_valid_pkg_name(utils): 28 | ret = utils.run(['tdnf', 'provides', 'tdnf']) 29 | assert ret['retval'] == 0 30 | 31 | 32 | def test_provides_invalid_pkg_name(utils): 33 | ret = utils.run(['tdnf', 'provides', 'invalid_pkg_name']) 34 | assert ret['stderr'][0] == 'No data available' 35 | -------------------------------------------------------------------------------- /pytests/tests/test_repo_missing_metadata.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | REPODIR = '/root/repo_missing_metadata/yum.repos.d' 14 | REPOFILENAME = 'repo_missing_metadata.repo' 15 | REPONAME = "repo_missing_metadata-test" 16 | WORKDIR = '/tmp/repo_missing_metadata/workdir' 17 | 18 | 19 | @pytest.fixture(scope='function', autouse=True) 20 | def setup_test(utils): 21 | yield 22 | teardown_test(utils) 23 | 24 | 25 | def teardown_test(utils): 26 | if os.path.isdir(REPODIR): 27 | shutil.rmtree(REPODIR) 28 | if os.path.isdir(WORKDIR): 29 | shutil.rmtree(WORKDIR) 30 | 31 | 32 | def test_repo_no_filelists(utils): 33 | reponame = 'photon-test' 34 | workdir = WORKDIR 35 | utils.makedirs(workdir) 36 | 37 | ret = utils.run(['tdnf', '--repo={}'.format(reponame), 38 | '--download-metadata', 39 | 'reposync'], 40 | cwd=workdir) 41 | assert ret['retval'] == 0 42 | synced_dir = os.path.join(workdir, reponame) 43 | assert os.path.isdir(synced_dir) 44 | assert os.path.isdir(os.path.join(synced_dir, 'repodata')) 45 | assert os.path.isfile(os.path.join(synced_dir, 'repodata', 'repomd.xml')) 46 | 47 | for file in ['filelists', 'filelists_db']: 48 | ret = utils.run(['modifyrepo', '--remove', file, os.path.join(synced_dir, 'repodata')]) 49 | assert ret['retval'] == 0 50 | 51 | ret = utils.run(['tdnf', 52 | '--repofrompath=synced-repo,{}'.format(synced_dir), 53 | '--repo=synced-repo', 54 | 'makecache'], 55 | cwd=workdir) 56 | assert ret['retval'] == 0 57 | -------------------------------------------------------------------------------- /pytests/tests/test_repogpgcheck.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import pytest 11 | 12 | PLUGIN_NAME = 'tdnfrepogpgcheck' 13 | 14 | 15 | @pytest.fixture(scope='module', autouse=True) 16 | def setup_test(utils): 17 | yield 18 | teardown_test(utils) 19 | 20 | 21 | def teardown_test(utils): 22 | utils.edit_config({'plugins': '0', 23 | 'pluginconfpath': None, 24 | 'pluginpath': None}) 25 | plugin_conf_path = os.path.join(utils.config['repo_path'], 'pluginconf.d') 26 | plugin_conf = os.path.join(plugin_conf_path, PLUGIN_NAME + '.conf') 27 | os.remove(plugin_conf) 28 | utils.edit_config({'repo_gpgcheck': None}, repo='photon-test') 29 | 30 | 31 | def enable_plugins(utils): 32 | # write a plugin config file 33 | plugin_conf_path = os.path.join(utils.config['repo_path'], 'pluginconf.d') 34 | plugin_path = utils.config['plugin_path'] 35 | utils.makedirs(plugin_conf_path) 36 | 37 | utils.edit_config({'plugins': '1', 38 | 'pluginconfpath': plugin_conf_path, 39 | 'pluginpath': plugin_path}) 40 | 41 | plugin_conf = os.path.join(plugin_conf_path, PLUGIN_NAME + '.conf') 42 | with open(plugin_conf, 'w') as plugin_conf_file: 43 | plugin_conf_file.write('[main]\nenabled=1\n') 44 | 45 | 46 | def set_plugin_flag_in_conf(utils, flag): 47 | utils.edit_config({'plugins': flag}) 48 | 49 | 50 | def set_plugin_config_enabled_flag(utils, flag): 51 | plugin_conf = os.path.join(utils.config['repo_path'], 'pluginconf.d', PLUGIN_NAME + '.conf') 52 | utils.edit_config({'enabled': flag}, filename=plugin_conf, section='main') 53 | 54 | 55 | def set_repo_flag_repo_gpgcheck(utils, flag): 56 | utils.edit_config({'repo_gpgcheck': flag, 'skip_if_unavailable': 'False'}, repo='photon-test') 57 | 58 | 59 | # make sure libtdnfrepogpgcheck.so is loaded without issues 60 | def test_tdnfrepogpgcheck_plugin_load(utils): 61 | enable_plugins(utils) 62 | ret = utils.run(['tdnf', 'repolist']) 63 | # we should load the plugin 64 | assert ret['stdout'][0].startswith('Loaded plugin: tdnfrepogpgcheck') # nosec 65 | # we should also pass the repolist command 66 | assert ret['retval'] == 0 # nosec 67 | 68 | 69 | # make sure libtdnfrepogpgcheck.so is used to validate repo signature 70 | def test_tdnfrepogpgcheck_plugin_validatesignature(utils): 71 | set_repo_flag_repo_gpgcheck(utils, "1") 72 | ret = utils.run(['tdnf', 'repolist', '--refresh']) 73 | # we should load the plugin 74 | assert ret['stdout'][0].startswith('Loaded plugin: tdnfrepogpgcheck') # nosec 75 | assert ret['retval'] == 0 76 | -------------------------------------------------------------------------------- /pytests/tests/test_repoid.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | REPODIR = '/root/repoid/yum.repos.d' 14 | REPOFILENAME = 'repoid.repo' 15 | REPONAME = "repoid-test" 16 | WORKDIR = '/root/repoid/workdir' 17 | 18 | 19 | @pytest.fixture(scope='function', autouse=True) 20 | def setup_test(utils): 21 | yield 22 | teardown_test(utils) 23 | 24 | 25 | def teardown_test(utils): 26 | if os.path.isdir(REPODIR): 27 | shutil.rmtree(REPODIR) 28 | if os.path.isdir(WORKDIR): 29 | shutil.rmtree(WORKDIR) 30 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 31 | if os.path.isfile(filename): 32 | os.remove(filename) 33 | 34 | 35 | def test_repoid(utils): 36 | utils.makedirs(REPODIR) 37 | utils.create_repoconf(os.path.join(REPODIR, REPOFILENAME), 38 | "http://foo.bar.com/packages", 39 | REPONAME) 40 | ret = utils.run(['tdnf', 41 | '--setopt=reposdir={}'.format(REPODIR), 42 | '--repoid={}'.format(REPONAME), 43 | 'repolist']) 44 | assert ret['retval'] == 0 45 | assert REPONAME in "\n".join(ret['stdout']) 46 | 47 | 48 | def test_repo(utils): 49 | utils.makedirs(REPODIR) 50 | utils.create_repoconf(os.path.join(REPODIR, REPOFILENAME), 51 | "http://foo.bar.com/packages", 52 | REPONAME) 53 | ret = utils.run(['tdnf', 54 | '--setopt=reposdir={}'.format(REPODIR), 55 | '--repo={}'.format(REPONAME), 56 | 'repolist']) 57 | assert ret['retval'] == 0 58 | assert REPONAME in "\n".join(ret['stdout']) 59 | 60 | 61 | # reposync a repo and install from it 62 | def test_repoid_created_repo(utils): 63 | reponame = 'photon-test' 64 | workdir = WORKDIR 65 | utils.makedirs(workdir) 66 | 67 | ret = utils.run(['tdnf', '--repo={}'.format(reponame), 68 | '--download-metadata', 69 | 'reposync'], 70 | cwd=workdir) 71 | assert ret['retval'] == 0 72 | synced_dir = os.path.join(workdir, reponame) 73 | assert os.path.isdir(synced_dir) 74 | assert os.path.isdir(os.path.join(synced_dir, 'repodata')) 75 | assert os.path.isfile(os.path.join(synced_dir, 'repodata', 'repomd.xml')) 76 | 77 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 78 | baseurl = "file://{}".format(synced_dir) 79 | 80 | utils.create_repoconf(filename, baseurl, "synced-repo") 81 | 82 | ret = utils.run(['tdnf', 83 | '--repo=synced-repo', 84 | 'makecache'], 85 | cwd=workdir) 86 | assert ret['retval'] == 0 87 | 88 | pkgname = utils.config["mulversion_pkgname"] 89 | utils.erase_package(pkgname) 90 | ret = utils.run(['tdnf', 91 | '-y', '--nogpgcheck', 92 | '--repo=synced-repo', 93 | 'install', pkgname], 94 | cwd=workdir) 95 | assert ret['retval'] == 0 96 | assert utils.check_package(pkgname) 97 | -------------------------------------------------------------------------------- /pytests/tests/test_rpmdefine.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | 14 | INSTALLROOT = '/root/installroot' 15 | REPOFILENAME = 'photon-test.repo' 16 | 17 | 18 | @pytest.fixture(scope='function', autouse=True) 19 | def setup_test(utils): 20 | yield 21 | teardown_test(utils) 22 | 23 | 24 | def teardown_test(utils): 25 | if os.path.isdir(INSTALLROOT): 26 | shutil.rmtree(INSTALLROOT) 27 | 28 | 29 | @pytest.mark.parametrize("dbpath", ["/usr/lib/rpm", "/usr/lib/sysimage/rpm/"]) 30 | def test_install(utils, dbpath): 31 | pkgname = utils.config["mulversion_pkgname"] 32 | ret = utils.run(['tdnf', 'install', 33 | '-y', '--nogpgcheck', 34 | '--installroot', INSTALLROOT, 35 | '--releasever=5.0', 36 | '--rpmdefine', f"_dbpath {dbpath}", 37 | pkgname]) 38 | assert ret['retval'] == 0 39 | assert os.path.isdir(os.path.join(INSTALLROOT, dbpath.lstrip("/"))) 40 | assert os.path.isfile(os.path.join(INSTALLROOT, dbpath.lstrip("/"), "rpmdb.sqlite")) 41 | -------------------------------------------------------------------------------- /pytests/tests/test_search.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_search_no_arg(utils): 23 | ret = utils.run(['tdnf', 'search']) 24 | assert ret['retval'] == 1599 25 | 26 | 27 | def test_search_invalid_arg(utils): 28 | ret = utils.run(['tdnf', 'search', 'invalid_arg']) 29 | assert ret['retval'] == 1599 30 | 31 | 32 | def test_search_single(utils): 33 | ret = utils.run(['tdnf', 'search', 'tdnf']) 34 | assert ret['retval'] == 0 35 | 36 | 37 | def test_search_multiple(utils): 38 | ret = utils.run(['tdnf', 'search', 'tdnf', 'wget', 'gzip']) 39 | assert ret['retval'] == 0 40 | -------------------------------------------------------------------------------- /pytests/tests/test_setopt_reposdir.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | REPODIR = '/root/yum.repos.d' 14 | REPOFILENAME = 'setopt.repo' 15 | REPONAME = "reposdir-test" 16 | 17 | 18 | @pytest.fixture(scope='function', autouse=True) 19 | def setup_test(utils): 20 | yield 21 | teardown_test(utils) 22 | 23 | 24 | def teardown_test(utils): 25 | if os.path.isdir(REPODIR): 26 | shutil.rmtree(REPODIR) 27 | 28 | 29 | def test_setopt_reposdir(utils): 30 | utils.makedirs(REPODIR) 31 | utils.create_repoconf(os.path.join(REPODIR, REPOFILENAME), 32 | "http://foo.bar.com/packages", 33 | REPONAME) 34 | ret = utils.run(['tdnf', '--setopt=reposdir={}'.format(REPODIR), 'repolist']) 35 | assert ret['retval'] == 0 36 | assert REPONAME in "\n".join(ret['stdout']) 37 | -------------------------------------------------------------------------------- /pytests/tests/test_srpms.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 - 2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import glob 10 | import os 11 | import platform 12 | import pytest 13 | import shutil 14 | 15 | ARCH = platform.machine() 16 | 17 | DIST = os.environ.get('DIST') 18 | # dir that holds the SPECS dir: 19 | if DIST == 'fedora': 20 | RPMBUILD_DIR = '/root/rpmbuild' 21 | else: 22 | RPMBUILD_DIR = '/usr/src/photon' 23 | 24 | 25 | @pytest.fixture(scope='function', autouse=True) 26 | def setup_test(utils): 27 | yield 28 | teardown_test(utils) 29 | 30 | 31 | def teardown_test(utils): 32 | if (os.path.isdir(RPMBUILD_DIR)): 33 | shutil.rmtree(RPMBUILD_DIR) 34 | 35 | 36 | def get_pkg_file_path(utils, pkgname): 37 | dir = os.path.join(utils.config['repo_path'], 'photon-test', 'RPMS', ARCH) 38 | matches = glob.glob('{}/{}-*.rpm'.format(dir, pkgname)) 39 | return matches[0] 40 | 41 | 42 | def get_srcpkg_file_path(utils, pkgname): 43 | dir = os.path.join(utils.config['repo_path'], 'photon-test-src', 'SRPMS') 44 | matches = glob.glob('{}/{}-*.src.rpm'.format(dir, pkgname)) 45 | return matches[0] 46 | 47 | 48 | def test_install_srpm(utils): 49 | pkgname = utils.config["mulversion_pkgname"] 50 | utils.erase_package(pkgname) 51 | 52 | ret = utils.run(['tdnf', 'install', '--repoid=photon-test-src', '-y', '--source', '--nogpgcheck', pkgname]) 53 | assert ret['retval'] == 0 54 | assert not utils.check_package(pkgname) # source RPMs are never really installed 55 | 56 | assert len(glob.glob(os.path.join(RPMBUILD_DIR, 'SPECS', '*.spec'))) > 0 57 | 58 | 59 | def test_install_srpm_file_with_source_option(utils): 60 | pkgname = utils.config["sglversion_pkgname"] 61 | path = get_srcpkg_file_path(utils, pkgname) 62 | ret = utils.run(['tdnf', 'install', '-y', '--source', '--nogpgcheck', path]) 63 | assert ret['retval'] == 0 64 | 65 | assert len(glob.glob(os.path.join(RPMBUILD_DIR, 'SPECS', '*.spec'))) > 0 66 | 67 | 68 | # test srpm install if binary is installed (issue #515) 69 | def test_install_srpm_binary_isinstalled(utils): 70 | pkgname = utils.config["mulversion_pkgname"] 71 | utils.erase_package(pkgname) 72 | 73 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', pkgname]) 74 | assert ret['retval'] == 0 75 | ret = utils.run(['tdnf', 'install', '--repoid=photon-test-src', '-y', '--source', '--nogpgcheck', pkgname]) 76 | assert ret['retval'] == 0 77 | 78 | assert len(glob.glob(os.path.join(RPMBUILD_DIR, 'SPECS', '*.spec'))) > 0 79 | 80 | 81 | # fail if trying to install an rpm with --source option 82 | def test_install_rpm_file_with_source_option(utils): 83 | pkgname = utils.config["sglversion_pkgname"] 84 | path = get_pkg_file_path(utils, pkgname) 85 | ret = utils.run(['tdnf', 'install', '-y', '--source', '--nogpgcheck', path]) 86 | assert ret['retval'] != 0 87 | 88 | 89 | # fail if trying to install an srpm without --source option 90 | def test_install_srpm_file_without_source_option(utils): 91 | pkgname = utils.config["sglversion_pkgname"] 92 | path = get_srcpkg_file_path(utils, pkgname) 93 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', path]) 94 | assert ret['retval'] != 0 95 | -------------------------------------------------------------------------------- /pytests/tests/test_update.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | mpkg = utils.config["mulversion_pkgname"] 20 | spkg = utils.config["sglversion_pkgname"] 21 | utils.run(['tdnf', 'erase', '-y', spkg, mpkg]) 22 | 23 | 24 | def test_update_invalid_arg(utils): 25 | ret = utils.run(['tdnf', 'update', '-y', 'invalid_package']) 26 | assert ret['retval'] == 1011 27 | 28 | 29 | def test_update_single_version_package(utils): 30 | spkg = utils.config["sglversion_pkgname"] 31 | if not utils.check_package(spkg): 32 | utils.install_package(spkg) 33 | ret = utils.run(['tdnf', 'update', '-y', spkg]) 34 | assert ret['stderr'][0] == 'Nothing to do.' 35 | 36 | 37 | def test_update_multi_version_package(utils): 38 | mpkg = utils.config["mulversion_pkgname"] 39 | mpkg_version = utils.config["mulversion_lower"] 40 | 41 | if utils.check_package(mpkg): 42 | utils.erase_package(mpkg) 43 | 44 | # install lower version 45 | utils.install_package(mpkg, mpkg_version) 46 | 47 | # perform an upgrade 48 | ret = utils.run(['tdnf', 'update', '-y', '--nogpgcheck', mpkg]) 49 | assert ret['retval'] == 0 50 | 51 | # Verify that it cannot be further upgraded 52 | ret = utils.run(['tdnf', 'update', '-y', mpkg]) 53 | assert ret['stderr'][0] == 'Nothing to do.' 54 | -------------------------------------------------------------------------------- /pytests/tests/test_updateinfo.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='function', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | mpkg = utils.config["mulversion_pkgname"] 20 | spkg = utils.config["sglversion_pkgname"] 21 | utils.run(['tdnf', 'erase', '-y', mpkg, spkg]) 22 | 23 | 24 | def helper_test_updateinfo_sub_cmd(utils, sub_cmd): 25 | ret = utils.run(['tdnf', 'updateinfo', sub_cmd]) 26 | assert ret['retval'] == 0 27 | ret = utils.run(['tdnf', 'updateinfo', sub_cmd, utils.config["sglversion_pkgname"]]) 28 | assert ret['retval'] == 0 29 | ret = utils.run(['tdnf', 'updateinfo', sub_cmd, 'invalid_package']) 30 | assert ret['retval'] == 1011 31 | 32 | 33 | def test_updateinfo_top(utils): 34 | spkg = utils.config["sglversion_pkgname"] 35 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 36 | assert ret['retval'] == 0 37 | 38 | ret = utils.run(['tdnf', 'updateinfo']) 39 | assert ret['retval'] == 0 40 | ret = utils.run(['tdnf', 'updateinfo', utils.config["sglversion_pkgname"]]) 41 | assert ret['retval'] == 0 42 | ret = utils.run(['tdnf', 'updateinfo', 'invalid_package']) 43 | assert ret['retval'] == 1011 44 | 45 | 46 | def test_updateinfo_sub_cmd(utils): 47 | spkg = utils.config["sglversion_pkgname"] 48 | ret = utils.run(['tdnf', 'install', '-y', spkg]) 49 | assert ret['retval'] == 0 50 | 51 | for arg in ['all', 'installed', 'available', 'obsoletes', 'extras', 'recent', 52 | 'summary', 'list', 'info']: 53 | helper_test_updateinfo_sub_cmd(utils, arg) 54 | helper_test_updateinfo_sub_cmd(utils, '--' + arg) 55 | 56 | 57 | def test_updateinfo_notinstalled(utils): 58 | mpkg = utils.config["mulversion_pkgname"] 59 | mpkg_version = utils.config["mulversion_lower"] 60 | spkg = utils.config["sglversion_pkgname"] 61 | 62 | ret = utils.run(['tdnf', 'updateinfo', 'upgrades']) 63 | assert ret['retval'] == 0 64 | 65 | utils.run(['tdnf', 'install', '-y', '--nogpgcheck', mpkg + '-' + mpkg_version]) 66 | ret = utils.run(['tdnf', 'updateinfo', 'upgrades', mpkg]) 67 | assert len(ret['stdout']) == 1 68 | 69 | for cmd in ['updates', 'upgrades', 'downgrades', '--updates', '--upgrades', '--downgrades']: 70 | ret = utils.run(['tdnf', 'updateinfo', cmd, 'invalid_package']) 71 | assert ret['retval'] == 1011 72 | 73 | # spkg is not installed, expect error 74 | ret = utils.run(['tdnf', 'updateinfo', cmd, spkg]) 75 | assert ret['retval'] == 1011 76 | -------------------------------------------------------------------------------- /pytests/tests/test_vars.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Broadcom, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import os 10 | import shutil 11 | import pytest 12 | 13 | WORKDIR = '/root/vars/workdir' 14 | REPOFILENAME = 'baseurls.repo' 15 | REPONAME = 'baseurls-repo' 16 | 17 | 18 | @pytest.fixture(scope='module', autouse=True) 19 | def setup_test(utils): 20 | workdir = WORKDIR 21 | utils.makedirs(workdir) 22 | utils.edit_config({'varsdir': workdir}) 23 | 24 | yield 25 | teardown_test(utils) 26 | 27 | 28 | def teardown_test(utils): 29 | pkgname = utils.config["mulversion_pkgname"] 30 | utils.erase_package(pkgname) 31 | if os.path.isdir(WORKDIR): 32 | shutil.rmtree(WORKDIR) 33 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 34 | if os.path.isfile(filename): 35 | os.remove(filename) 36 | 37 | 38 | def test_vars(utils): 39 | reponame = REPONAME 40 | workdir = WORKDIR 41 | 42 | varsdir = workdir 43 | port_var = "8080" 44 | dir_var = "photon-test" 45 | 46 | with open(os.path.join(varsdir, "port"), "wt") as f: 47 | f.write(port_var + "\n") 48 | 49 | with open(os.path.join(varsdir, "dir"), "wt") as f: 50 | f.write(dir_var + "\n") 51 | 52 | filename = os.path.join(utils.config['repo_path'], "yum.repos.d", REPOFILENAME) 53 | 54 | baseurls = "http://localhost:$port/$dir" 55 | utils.create_repoconf(filename, baseurls, reponame) 56 | 57 | ret = utils.run(['tdnf', 58 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 59 | 'makecache'], 60 | cwd=workdir) 61 | assert ret['retval'] == 0 62 | 63 | pkgname = utils.config["mulversion_pkgname"] 64 | utils.erase_package(pkgname) 65 | ret = utils.run(['tdnf', 66 | '-y', '--nogpgcheck', 67 | '--disablerepo=*', '--enablerepo={}'.format(reponame), 68 | 'install', pkgname], 69 | cwd=workdir) 70 | assert utils.check_package(pkgname) 71 | -------------------------------------------------------------------------------- /pytests/tests/test_version.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_version(utils): 23 | expected_version_string = utils.config['project_name'] + ': ' + \ 24 | utils.config['project_version'] 25 | ret = utils.run(['tdnf', '--version']) 26 | assert ret['retval'] == 0 27 | assert ret['stdout'][0] == expected_version_string 28 | 29 | 30 | # memcheck 31 | def test_version_memcheck(utils): 32 | ret = utils.run_memcheck(['tdnf', '--version']) 33 | assert ret['retval'] == 0 34 | -------------------------------------------------------------------------------- /pytests/tests/test_whatprovides.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | import pytest 10 | 11 | 12 | @pytest.fixture(scope='module', autouse=True) 13 | def setup_test(utils): 14 | yield 15 | teardown_test(utils) 16 | 17 | 18 | def teardown_test(utils): 19 | pass 20 | 21 | 22 | def test_whatprovides_no_arg(utils): 23 | ret = utils.run(['tdnf', 'whatprovides']) 24 | assert ret['retval'] == 907 25 | 26 | 27 | def test_whatprovides_invalid_arg(utils): 28 | ret = utils.run(['tdnf', 'whatprovides', 'invalid_arg']) 29 | assert ret['stderr'][0] == 'No data available' 30 | 31 | 32 | def test_whatprovides_valid_file_notinstalled(utils): 33 | ret = utils.run(['tdnf', 'whatprovides', '/lib/systemd/system/tdnf-test-one.service']) 34 | assert 'tdnf-test-one' in "\n".join(ret['stdout']) 35 | assert ret['retval'] == 0 36 | 37 | 38 | def test_whatprovides_valid_file_installed(utils): 39 | ret = utils.run(['tdnf', 'install', '-y', '--nogpgcheck', 'tdnf-test-one']) 40 | ret = utils.run(['tdnf', 'whatprovides', '/lib/systemd/system/tdnf-test-one.service']) 41 | assert 'tdnf-test-one' in "\n".join(ret['stdout']) 42 | assert ret['retval'] == 0 43 | -------------------------------------------------------------------------------- /scripts/build-tdnf-rpms.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | ## file: build-tdnf-rpms.sh 5 | ## brief: Build tdnf rpms using tdnf.spec 6 | ## author: Shreenidhi Shedi 7 | 8 | if [ ${EUID} -ne 0 ]; then 9 | echo "Script must be run as root." 1>&2 10 | exit 1 11 | fi 12 | 13 | arch="$(uname -m)" 14 | project_name="@PROJECT_NAME@" 15 | project_dir="@CMAKE_SOURCE_DIR@" 16 | rpmdir="${1:-rpms}" 17 | 18 | cd "${project_dir}" 19 | project_version="@PROJECT_VERSION@" 20 | rpm_build_path="${project_dir}/rpmbuild" 21 | full_name="${project_name}-${project_version}" 22 | specfile="${project_name}".spec 23 | 24 | build_tools=(git tar gzip file findutils) 25 | build_deps=$(rpmspec --parse $specfile | grep ^BuildRequires: | awk '{ print $2;}') 26 | 27 | if ! rpm -q ${build_tools[@]} > /dev/null; then 28 | echo "Installing required build tools..." 29 | if grep -w ID /etc/os-release | grep -i photon > /dev/null; then 30 | tdnf install -y ${build_tools[@]} 31 | tdnf install -y ${build_deps} 32 | elif grep -w ID /etc/os-release | grep -i fedora > /dev/null; then 33 | dnf install -y ${build_tools[@]} 34 | dnf install -y ${build_deps} 35 | fi 36 | fi 37 | 38 | # https://github.com/actions/checkout/issues/760 39 | git config --global --add safe.directory $(pwd) 40 | 41 | echo "Building ${full_name} RPMs" 42 | tar zcf ${full_name}.tar.gz --transform "s,^,${full_name}/," $(git ls-files) 43 | 44 | rm -rf "${rpm_build_path}" 45 | mkdir -p "${rpm_build_path}"/{SOURCES,BUILD,RPMS/"${arch}"} 46 | 47 | mv -f "${full_name}".tar.gz "${rpm_build_path}"/SOURCES 48 | 49 | dist=$(rpm -q glibc | cut -d'.' -f3) 50 | rpmbuild --nocheck -D "dist .${dist}" -D "_topdir ${rpm_build_path}" -bb "${project_name}".spec 51 | 52 | mkdir -p ${rpmdir} 53 | mv -f "${rpm_build_path}"/RPMS/"${arch}"/*.rpm ${rpmdir} 54 | echo -e "\n\n--- tdnf rpms are available at $(realpath ${rpmdir}) ---\n\n" 55 | -------------------------------------------------------------------------------- /scripts/llvm-tdnf-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | pkgs=(llvm-devel clang-devel) 6 | pkgs+=(which gcc cmake make) 7 | 8 | tdnf install -y --refresh ${pkgs[@]} 9 | 10 | export CC="$(which clang)" 11 | export CFLAGS="-Qunused-arguments -Wno-deprecated -Werror" 12 | 13 | [ -d build ] && rm -rf build 14 | mkdir -p build 15 | cd build || exit 1 16 | 17 | JOBS=$(( ($(nproc)+1) / 2 )) 18 | HIST_DB_DIR="/usr/lib/sysimage/tdnf" 19 | 20 | { 21 | mkdir -p ${HIST_DB_DIR} 22 | cmake -DHISTORY_DB_DIR=${HIST_DB_DIR} .. 23 | make -j${JOBS} 24 | make check -j${JOBS} 25 | } || exit 1 26 | -------------------------------------------------------------------------------- /solv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | include_directories(${CMAKE_SOURCE_DIR}/include) 10 | 11 | add_library(${LIB_TDNF_SOLV} STATIC 12 | tdnfpackage.c 13 | tdnfpool.c 14 | tdnfquery.c 15 | tdnfrepo.c 16 | simplequery.c 17 | ) 18 | -------------------------------------------------------------------------------- /solv/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef __SOLV_DEFINES_H__ 2 | #define __SOLV_DEFINES_H__ 3 | 4 | #define SYSTEM_REPO_NAME "@System" 5 | #define CMDLINE_REPO_NAME "@cmdline" 6 | #define SOLV_COOKIE_IDENT "tdnf" 7 | #define TDNF_SOLVCACHE_DIR_NAME "solvcache" 8 | #define SOLV_COOKIE_LEN 32 9 | 10 | #define SOLV_NEVRA_UNINSTALLED 0 11 | #define SOLV_NEVRA_INSTALLED 1 12 | 13 | #define BAIL_ON_TDNF_LIBSOLV_ERROR(dwError) \ 14 | do { \ 15 | if (dwError) \ 16 | { \ 17 | goto error; \ 18 | } \ 19 | } while(0) 20 | 21 | #endif /* __SOLV_DEFINES_H__ */ 22 | -------------------------------------------------------------------------------- /solv/includes.h: -------------------------------------------------------------------------------- 1 | #ifndef __SOLV_INCLUDES_H__ 2 | #define __SOLV_INCLUDES_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // libsolv 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | 39 | #include "defines.h" 40 | #include "tdnferror.h" 41 | #include "../common/defines.h" 42 | #include "../common/structs.h" 43 | #include "../common/prototypes.h" 44 | #include "../history/history.h" 45 | #include "prototypes.h" 46 | 47 | #endif /* __SOLV_INCLUDES_H__ */ 48 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | add_subdirectory("cli") 10 | add_subdirectory("config") 11 | -------------------------------------------------------------------------------- /tools/cli/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | set(TDNF_BIN tdnf-bin) 10 | 11 | add_executable(${TDNF_BIN} 12 | main.c 13 | ) 14 | 15 | target_link_libraries(${TDNF_BIN} 16 | ${SQLITE3_LIBRARIES} 17 | ${LIB_TDNF_CLI} 18 | ${LIB_TDNF} 19 | ) 20 | 21 | set_target_properties(${TDNF_BIN} PROPERTIES OUTPUT_NAME tdnf) 22 | 23 | install(TARGETS ${TDNF_BIN} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT binary) 24 | 25 | add_subdirectory("lib") 26 | -------------------------------------------------------------------------------- /tools/cli/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __CLI_INCLUDES_H__ 10 | #define __CLI_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "defines.h" 29 | #include "prototypes.h" 30 | #include "../common/structs.h" 31 | #include "../common/prototypes.h" 32 | #include "../jsondump/jsondump.h" 33 | 34 | #endif /* __CLI_INCLUDES_H__ */ 35 | -------------------------------------------------------------------------------- /tools/cli/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2022 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | # configure pkgconfig file 10 | configure_file( 11 | tdnf-cli-libs.pc.in 12 | tdnf-cli-libs.pc @ONLY 13 | ) 14 | 15 | add_library(${LIB_TDNF_CLI} SHARED 16 | api.c 17 | help.c 18 | installcmd.c 19 | options.c 20 | output.c 21 | parseargs.c 22 | parsecleanargs.c 23 | parselistargs.c 24 | parsehistoryargs.c 25 | parserepolistargs.c 26 | parserepoqueryargs.c 27 | parsereposyncargs.c 28 | parseupdateinfo.c 29 | updateinfocmd.c 30 | ) 31 | 32 | target_link_libraries(${LIB_TDNF_CLI} 33 | ${LIB_TDNF_JSONDUMP} 34 | ) 35 | 36 | set_target_properties(${LIB_TDNF_CLI} PROPERTIES 37 | VERSION ${PROJECT_VERSION} 38 | SOVERSION ${PROJECT_VERSION_MAJOR} 39 | ) 40 | 41 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdnf-cli-libs.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 42 | install(TARGETS ${LIB_TDNF_CLI} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library) 43 | -------------------------------------------------------------------------------- /tools/cli/lib/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #ifndef __CLI_LIB_INCLUDES_H__ 10 | #define __CLI_LIB_INCLUDES_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "../defines.h" 28 | #include "prototypes.h" 29 | #include "../common/structs.h" 30 | #include "../common/prototypes.h" 31 | #include "../jsondump/jsondump.h" 32 | 33 | #endif /* __CLI_LIB_INCLUDES_H__ */ 34 | -------------------------------------------------------------------------------- /tools/cli/lib/output.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | uint32_t 12 | GetConsoleWidth( 13 | int *pnConsoleWidth 14 | ) 15 | { 16 | uint32_t dwError = 0; 17 | struct winsize stWinSize = {0}; 18 | int nConsoleWidth = 0; 19 | 20 | if(!pnConsoleWidth) 21 | { 22 | dwError = ERROR_TDNF_INVALID_PARAMETER; 23 | BAIL_ON_CLI_ERROR(dwError); 24 | } 25 | 26 | dwError = ioctl(STDOUT_FILENO, TIOCGWINSZ, &stWinSize); 27 | if(dwError > 0) 28 | { 29 | nConsoleWidth = 80; 30 | dwError = 0; 31 | } 32 | else 33 | { 34 | nConsoleWidth = stWinSize.ws_col; 35 | } 36 | *pnConsoleWidth = nConsoleWidth; 37 | 38 | cleanup: 39 | return dwError; 40 | error: 41 | goto cleanup; 42 | } 43 | 44 | uint32_t 45 | GetColumnWidths( 46 | int nCount, 47 | const int *pnColPercents, 48 | int *pnColWidths 49 | ) 50 | { 51 | uint32_t dwError = 0; 52 | int nConsoleWidth = 0; 53 | int nIndex = 0; 54 | 55 | if(!pnColPercents || !pnColWidths) 56 | { 57 | dwError = ERROR_TDNF_INVALID_PARAMETER; 58 | BAIL_ON_CLI_ERROR(dwError); 59 | } 60 | 61 | dwError = GetConsoleWidth(&nConsoleWidth); 62 | BAIL_ON_CLI_ERROR(dwError); 63 | 64 | for(nIndex = 0; nIndex < nCount; nIndex++) 65 | { 66 | pnColWidths[nIndex] = (nConsoleWidth * pnColPercents[nIndex]) / 100; 67 | } 68 | cleanup: 69 | return dwError; 70 | error: 71 | goto cleanup; 72 | } 73 | -------------------------------------------------------------------------------- /tools/cli/lib/parsecleanargs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2022 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | uint32_t 12 | TDNFCliParseCleanArgs( 13 | PTDNF_CMD_ARGS pCmdArgs, 14 | uint32_t* pnCleanType 15 | ) 16 | { 17 | uint32_t dwError = 0; 18 | uint32_t nCleanType = CLEANTYPE_NONE; 19 | 20 | if(!pCmdArgs) 21 | { 22 | dwError = ERROR_TDNF_INVALID_PARAMETER; 23 | BAIL_ON_CLI_ERROR(dwError); 24 | } 25 | if(pCmdArgs->nCmdCount == 1) 26 | { 27 | dwError = ERROR_TDNF_CLI_CLEAN_REQUIRES_OPTION; 28 | BAIL_ON_CLI_ERROR(dwError); 29 | } 30 | 31 | //Should have type argument (tdnf clean ) 32 | if(pCmdArgs->nCmdCount > 1) 33 | { 34 | dwError = TDNFCliParseCleanType(pCmdArgs->ppszCmds[1], &nCleanType); 35 | BAIL_ON_CLI_ERROR(dwError); 36 | } 37 | 38 | *pnCleanType = nCleanType; 39 | 40 | cleanup: 41 | return dwError; 42 | 43 | error: 44 | if(pnCleanType) 45 | { 46 | *pnCleanType = CLEANTYPE_NONE; 47 | } 48 | goto cleanup; 49 | } 50 | 51 | uint32_t 52 | TDNFCliParseCleanType( 53 | const char* pszCleanType, 54 | uint32_t* pnCleanType 55 | ) 56 | { 57 | uint32_t dwError = 0; 58 | int nIndex = 0; 59 | uint32_t nCleanType = CLEANTYPE_ALL; 60 | struct stTemp 61 | { 62 | char* pszTypeName; 63 | int nType; 64 | }; 65 | struct stTemp stCleanTypes[] = 66 | { 67 | {"packages", CLEANTYPE_PACKAGES}, 68 | {"metadata", CLEANTYPE_METADATA}, 69 | {"dbcache", CLEANTYPE_DBCACHE}, 70 | {"plugins", CLEANTYPE_PLUGINS}, 71 | {"keys", CLEANTYPE_KEYS}, 72 | {"expire-cache", CLEANTYPE_EXPIRE_CACHE}, 73 | {"all", CLEANTYPE_ALL}, 74 | }; 75 | int nCount = ARRAY_SIZE(stCleanTypes); 76 | for(nIndex = 0; nIndex < nCount; ++nIndex) 77 | { 78 | if(!strcasecmp(stCleanTypes[nIndex].pszTypeName, pszCleanType)) 79 | { 80 | nCleanType = stCleanTypes[nIndex].nType; 81 | break; 82 | } 83 | } 84 | if(nIndex >= nCount) 85 | { 86 | dwError = ERROR_TDNF_CLI_NO_MATCH; 87 | } 88 | BAIL_ON_CLI_ERROR(dwError); 89 | 90 | *pnCleanType = nCleanType; 91 | cleanup: 92 | return dwError; 93 | 94 | error: 95 | if(pnCleanType) 96 | { 97 | *pnCleanType = CLEANTYPE_NONE; 98 | } 99 | goto cleanup; 100 | } 101 | -------------------------------------------------------------------------------- /tools/cli/lib/parserepolistargs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2020 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #include "includes.h" 10 | 11 | uint32_t 12 | TDNFCliParseRepoListArgs( 13 | PTDNF_CMD_ARGS pCmdArgs, 14 | TDNF_REPOLISTFILTER* pnFilter 15 | ) 16 | { 17 | uint32_t dwError = 0; 18 | TDNF_REPOLISTFILTER nFilter = REPOLISTFILTER_ENABLED; 19 | 20 | if(!pCmdArgs) 21 | { 22 | dwError = ERROR_TDNF_INVALID_PARAMETER; 23 | BAIL_ON_CLI_ERROR(dwError); 24 | } 25 | 26 | //Could have filter argument (tdnf repolist ) 27 | //assume REPOLISTFILTER_ENABLED if not specified. 28 | if(pCmdArgs->nCmdCount > 1) 29 | { 30 | dwError = TDNFCliParseFilter(pCmdArgs->ppszCmds[1], &nFilter); 31 | BAIL_ON_CLI_ERROR(dwError); 32 | } 33 | 34 | *pnFilter = nFilter; 35 | 36 | cleanup: 37 | return dwError; 38 | 39 | error: 40 | if(pnFilter) 41 | { 42 | *pnFilter = REPOLISTFILTER_ENABLED; 43 | } 44 | goto cleanup; 45 | } 46 | 47 | uint32_t 48 | TDNFCliParseFilter( 49 | const char* pszFilter, 50 | TDNF_REPOLISTFILTER* pnFilter 51 | ) 52 | { 53 | uint32_t dwError = 0; 54 | int nIndex = 0; 55 | TDNF_REPOLISTFILTER nFilter = REPOLISTFILTER_ENABLED; 56 | struct stTemp 57 | { 58 | char* pszTypeName; 59 | int nType; 60 | }; 61 | struct stTemp stFilterTypes[] = 62 | { 63 | {"all", REPOLISTFILTER_ALL}, 64 | {"enabled", REPOLISTFILTER_ENABLED}, 65 | {"disabled", REPOLISTFILTER_DISABLED} 66 | }; 67 | int nCount = ARRAY_SIZE(stFilterTypes); 68 | for(nIndex = 0; nIndex < nCount; ++nIndex) 69 | { 70 | if(!strcasecmp(stFilterTypes[nIndex].pszTypeName, pszFilter)) 71 | { 72 | nFilter = stFilterTypes[nIndex].nType; 73 | break; 74 | } 75 | } 76 | if(nIndex >= nCount) 77 | { 78 | dwError = ERROR_TDNF_CLI_NO_MATCH; 79 | } 80 | BAIL_ON_CLI_ERROR(dwError); 81 | 82 | *pnFilter = nFilter; 83 | cleanup: 84 | return dwError; 85 | 86 | error: 87 | if(pnFilter) 88 | { 89 | *pnFilter = REPOLISTFILTER_ENABLED; 90 | } 91 | goto cleanup; 92 | } 93 | -------------------------------------------------------------------------------- /tools/cli/lib/prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2023 VMware, Inc. All Rights Reserved. 3 | * 4 | * Licensed under the GNU General Public License v2 (the "License"); 5 | * you may not use this file except in compliance with the License. The terms 6 | * of the License are located in the COPYING file of this distribution. 7 | */ 8 | 9 | #pragma once 10 | 11 | //parseargs.c 12 | uint32_t 13 | TDNFCopyOptions( 14 | PTDNF_CMD_ARGS pOptionArgs, 15 | PTDNF_CMD_ARGS pArgs 16 | ); 17 | 18 | uint32_t 19 | ParseOption( 20 | const char* pszName, 21 | const char* pszArg, 22 | PTDNF_CMD_ARGS pCmdArgs 23 | ); 24 | 25 | uint32_t 26 | ParseRpmVerbosity( 27 | const char* pszVerbosity, 28 | int* pnVerbosity 29 | ); 30 | 31 | uint32_t 32 | HandleOptionsError( 33 | const char* pszName, 34 | const char* pszArg, 35 | struct option* pstOptions 36 | ); 37 | 38 | //updateinfocmd.c 39 | char* 40 | TDNFGetUpdateInfoType( 41 | int nType 42 | ); 43 | 44 | uint32_t 45 | TDNFCliUpdateInfoSummary( 46 | PTDNF_CLI_CONTEXT pContext, 47 | PTDNF_CMD_ARGS pCmdArgs, 48 | PTDNF_UPDATEINFO_ARGS pInfoArgs 49 | ); 50 | 51 | uint32_t 52 | TDNFCliUpdateInfoOutput( 53 | PTDNF_UPDATEINFO pInfo, 54 | TDNF_UPDATEINFO_OUTPUT mode 55 | ); 56 | 57 | uint32_t 58 | TDNFCliUpdateInfoOutputJson( 59 | PTDNF_UPDATEINFO pInfo, 60 | TDNF_UPDATEINFO_OUTPUT mode 61 | ); 62 | 63 | //help.c 64 | void 65 | TDNFCliShowNoSuchOption( 66 | const char* pszOption 67 | ); 68 | 69 | //options.c 70 | uint32_t 71 | _TDNFCliGetOptionByName( 72 | const char* pszName, 73 | struct option* pKnownOptions, 74 | struct option** ppOption 75 | ); 76 | 77 | uint32_t 78 | TDNFCliValidateOptionName( 79 | const char* pszOptionName, 80 | struct option* pKnownOptions 81 | ); 82 | 83 | uint32_t 84 | TDNFCliValidateOptionArg( 85 | const char* pszOption, 86 | const char* pszArg, 87 | struct option* pKnownOptions 88 | ); 89 | 90 | uint32_t 91 | TDNFCliValidateOptions( 92 | const char* pszOption, 93 | const char* pszArg, 94 | struct option* pKnownOptions 95 | ); 96 | -------------------------------------------------------------------------------- /tools/cli/lib/tdnf-cli-libs.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/include/tdnf 4 | 5 | Name: tdnfcli 6 | Description: TDNF CLI interface library 7 | Version: @PROJECT_VERSION@ 8 | Provides: libtdnfcli = @PROJECT_VERSION@ 9 | Requires: tdnf = @PROJECT_VERSION@ 10 | Libs: -L${libdir} -ltdnfcli 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /tools/config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2023 VMware, Inc. All Rights Reserved. 3 | # 4 | # Licensed under the GNU General Public License v2 (the "License"); 5 | # you may not use this file except in compliance with the License. The terms 6 | # of the License are located in the COPYING file of this distribution. 7 | # 8 | 9 | set(TDNF_CONFIG_BIN tdnf-config-bin) 10 | 11 | add_executable(${TDNF_CONFIG_BIN} 12 | main.c 13 | ) 14 | 15 | target_link_libraries(${TDNF_CONFIG_BIN} 16 | ${LIB_TDNF_LLCONF} 17 | ${LIB_TDNF_JSONDUMP} 18 | ${CMAKE_DL_LIBS} 19 | ) 20 | 21 | set_target_properties(${TDNF_CONFIG_BIN} PROPERTIES OUTPUT_NAME tdnf-config) 22 | 23 | install(TARGETS ${TDNF_CONFIG_BIN} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT binary) 24 | 25 | #add_subdirectory("lib") 26 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude=._* 3 | ignore=E501 4 | --------------------------------------------------------------------------------